searchkick 4.2.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -3
- data/LICENSE.txt +1 -1
- data/README.md +253 -202
- data/lib/searchkick.rb +31 -12
- data/lib/searchkick/bulk_indexer.rb +1 -1
- data/lib/searchkick/index.rb +22 -2
- data/lib/searchkick/index_options.rb +468 -382
- data/lib/searchkick/model.rb +11 -6
- data/lib/searchkick/query.rb +40 -6
- data/lib/searchkick/results.rb +10 -0
- data/lib/searchkick/version.rb +1 -1
- data/lib/tasks/searchkick.rake +12 -11
- metadata +3 -46
- data/CONTRIBUTING.md +0 -53
data/lib/searchkick/model.rb
CHANGED
@@ -5,8 +5,8 @@ module Searchkick
|
|
5
5
|
|
6
6
|
unknown_keywords = options.keys - [:_all, :_type, :batch_size, :callbacks, :case_sensitive, :conversions, :deep_paging, :default_fields,
|
7
7
|
:filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :inheritance, :language,
|
8
|
-
:locations, :mappings, :match, :merge_mappings, :routing, :searchable, :settings, :similarity,
|
9
|
-
:special_characters, :stem, :stem_conversions, :suggest, :synonyms, :text_end,
|
8
|
+
:locations, :mappings, :match, :merge_mappings, :routing, :searchable, :search_synonyms, :settings, :similarity,
|
9
|
+
:special_characters, :stem, :stem_conversions, :stem_exclusion, :stemmer_override, :suggest, :synonyms, :text_end,
|
10
10
|
:text_middle, :text_start, :word, :wordnet, :word_end, :word_middle, :word_start]
|
11
11
|
raise ArgumentError, "unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any?
|
12
12
|
|
@@ -41,7 +41,10 @@ module Searchkick
|
|
41
41
|
|
42
42
|
class << self
|
43
43
|
def searchkick_search(term = "*", **options, &block)
|
44
|
-
|
44
|
+
# TODO throw error in next major version
|
45
|
+
Searchkick.warn("calling search on a relation is deprecated") if Searchkick.relation?(self)
|
46
|
+
|
47
|
+
Searchkick.search(term, model: self, **options, &block)
|
45
48
|
end
|
46
49
|
alias_method Searchkick.search_method_name, :searchkick_search if Searchkick.search_method_name
|
47
50
|
|
@@ -54,10 +57,11 @@ module Searchkick
|
|
54
57
|
alias_method :search_index, :searchkick_index unless method_defined?(:search_index)
|
55
58
|
|
56
59
|
def searchkick_reindex(method_name = nil, **options)
|
57
|
-
|
60
|
+
# TODO relation = Searchkick.relation?(self)
|
61
|
+
relation = (respond_to?(:current_scope) && respond_to?(:default_scoped) && current_scope && current_scope.to_sql != default_scoped.to_sql) ||
|
58
62
|
(respond_to?(:queryable) && queryable != unscoped.with_default_scope)
|
59
63
|
|
60
|
-
searchkick_index.reindex(searchkick_klass, method_name, scoped:
|
64
|
+
searchkick_index.reindex(searchkick_klass, method_name, scoped: relation, **options)
|
61
65
|
end
|
62
66
|
alias_method :reindex, :searchkick_reindex unless method_defined?(:reindex)
|
63
67
|
|
@@ -79,8 +83,9 @@ module Searchkick
|
|
79
83
|
RecordIndexer.new(self).reindex(method_name, **options)
|
80
84
|
end unless method_defined?(:reindex)
|
81
85
|
|
86
|
+
# TODO switch to keyword arguments
|
82
87
|
def similar(options = {})
|
83
|
-
self.class.searchkick_index.similar_record(self, options)
|
88
|
+
self.class.searchkick_index.similar_record(self, **options)
|
84
89
|
end unless method_defined?(:similar)
|
85
90
|
|
86
91
|
def search_data
|
data/lib/searchkick/query.rb
CHANGED
@@ -350,7 +350,7 @@ module Searchkick
|
|
350
350
|
field_misspellings = misspellings && (!misspellings_fields || misspellings_fields.include?(base_field(field)))
|
351
351
|
|
352
352
|
if field == "_all" || field.end_with?(".analyzed")
|
353
|
-
shared_options[:cutoff_frequency] = 0.001 unless operator.to_s == "and" || field_misspellings == false
|
353
|
+
shared_options[:cutoff_frequency] = 0.001 unless operator.to_s == "and" || field_misspellings == false || (!below73? && !track_total_hits?)
|
354
354
|
qs << shared_options.merge(analyzer: "searchkick_search")
|
355
355
|
|
356
356
|
# searchkick_search and searchkick_search2 are the same for ukrainian
|
@@ -522,7 +522,7 @@ module Searchkick
|
|
522
522
|
# routing
|
523
523
|
@routing = options[:routing] if options[:routing]
|
524
524
|
|
525
|
-
if
|
525
|
+
if track_total_hits?
|
526
526
|
payload[:track_total_hits] = true
|
527
527
|
end
|
528
528
|
|
@@ -574,7 +574,8 @@ module Searchkick
|
|
574
574
|
|
575
575
|
def build_query(query, filters, should, must_not, custom_filters, multiply_filters)
|
576
576
|
if filters.any? || must_not.any? || should.any?
|
577
|
-
bool = {
|
577
|
+
bool = {}
|
578
|
+
bool[:must] = query if query
|
578
579
|
bool[:filter] = filters if filters.any? # where
|
579
580
|
bool[:must_not] = must_not if must_not.any? # exclude
|
580
581
|
bool[:should] = should if should.any? # conversions
|
@@ -871,6 +872,11 @@ module Searchkick
|
|
871
872
|
end
|
872
873
|
|
873
874
|
def where_filters(where)
|
875
|
+
# if where.respond_to?(:permitted?) && !where.permitted?
|
876
|
+
# # TODO check in more places
|
877
|
+
# Searchkick.warn("Passing unpermitted parameters will raise an exception in Searchkick 5")
|
878
|
+
# end
|
879
|
+
|
874
880
|
filters = []
|
875
881
|
(where || {}).each do |field, value|
|
876
882
|
field = :_id if field.to_s == "id"
|
@@ -953,10 +959,17 @@ module Searchkick
|
|
953
959
|
# % matches zero or more characters
|
954
960
|
# _ matches one character
|
955
961
|
# \ is escape character
|
956
|
-
|
962
|
+
# escape Lucene reserved characters
|
963
|
+
# https://www.elastic.co/guide/en/elasticsearch/reference/current/regexp-syntax.html#regexp-optional-operators
|
964
|
+
reserved = %w(. ? + * | { } [ ] ( ) " \\)
|
965
|
+
regex = op_value.dup
|
966
|
+
reserved.each do |v|
|
967
|
+
regex.gsub!(v, "\\" + v)
|
968
|
+
end
|
969
|
+
regex = regex.gsub(/(?<!\\)%/, ".*").gsub(/(?<!\\)_/, ".").gsub("\\%", "%").gsub("\\_", "_")
|
957
970
|
filters << {regexp: {field => {value: regex}}}
|
958
971
|
when :prefix
|
959
|
-
filters << {prefix: {field => op_value}}
|
972
|
+
filters << {prefix: {field => {value: op_value}}}
|
960
973
|
when :regexp # support for regexp queries without using a regexp ruby object
|
961
974
|
filters << {regexp: {field => {value: op_value}}}
|
962
975
|
when :not, :_not # not equal
|
@@ -1036,7 +1049,16 @@ module Searchkick
|
|
1036
1049
|
|
1037
1050
|
{regexp: {field => {value: source, flags: "NONE"}}}
|
1038
1051
|
else
|
1039
|
-
|
1052
|
+
# TODO add this for other values
|
1053
|
+
if value.as_json.is_a?(Enumerable)
|
1054
|
+
# query will fail, but this is better
|
1055
|
+
# same message as Active Record
|
1056
|
+
# TODO make TypeError
|
1057
|
+
# raise InvalidQueryError for backward compatibility
|
1058
|
+
raise Searchkick::InvalidQueryError, "can't cast #{value.class.name}"
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
{term: {field => {value: value}}}
|
1040
1062
|
end
|
1041
1063
|
end
|
1042
1064
|
|
@@ -1100,6 +1122,14 @@ module Searchkick
|
|
1100
1122
|
k.sub(/\.(analyzed|word_start|word_middle|word_end|text_start|text_middle|text_end|exact)\z/, "")
|
1101
1123
|
end
|
1102
1124
|
|
1125
|
+
def track_total_hits?
|
1126
|
+
(searchkick_options[:deep_paging] && !below70?) || body_options[:track_total_hits]
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
def body_options
|
1130
|
+
options[:body_options] || {}
|
1131
|
+
end
|
1132
|
+
|
1103
1133
|
def below61?
|
1104
1134
|
Searchkick.server_below?("6.1.0")
|
1105
1135
|
end
|
@@ -1108,6 +1138,10 @@ module Searchkick
|
|
1108
1138
|
Searchkick.server_below?("7.0.0")
|
1109
1139
|
end
|
1110
1140
|
|
1141
|
+
def below73?
|
1142
|
+
Searchkick.server_below?("7.3.0")
|
1143
|
+
end
|
1144
|
+
|
1111
1145
|
def below75?
|
1112
1146
|
Searchkick.server_below?("7.5.0")
|
1113
1147
|
end
|
data/lib/searchkick/results.rb
CHANGED
@@ -19,6 +19,7 @@ module Searchkick
|
|
19
19
|
@results ||= with_hit.map(&:first)
|
20
20
|
end
|
21
21
|
|
22
|
+
# TODO return enumerator like with_score
|
22
23
|
def with_hit
|
23
24
|
@with_hit ||= begin
|
24
25
|
if options[:load]
|
@@ -211,12 +212,21 @@ module Searchkick
|
|
211
212
|
end
|
212
213
|
end
|
213
214
|
|
215
|
+
# TODO return enumerator like with_score
|
214
216
|
def with_highlights(multiple: false)
|
215
217
|
with_hit.map do |result, hit|
|
216
218
|
[result, hit_highlights(hit, multiple: multiple)]
|
217
219
|
end
|
218
220
|
end
|
219
221
|
|
222
|
+
def with_score
|
223
|
+
return enum_for(:with_score) unless block_given?
|
224
|
+
|
225
|
+
with_hit.each do |result, hit|
|
226
|
+
yield result, hit["_score"]
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
220
230
|
def misspellings?
|
221
231
|
@options[:misspellings]
|
222
232
|
end
|
data/lib/searchkick/version.rb
CHANGED
data/lib/tasks/searchkick.rake
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
namespace :searchkick do
|
2
|
-
desc "reindex model"
|
2
|
+
desc "reindex a model (specify CLASS)"
|
3
3
|
task reindex: :environment do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
class_name = ENV["CLASS"]
|
5
|
+
abort "USAGE: rake searchkick:reindex CLASS=Product" unless class_name
|
6
|
+
|
7
|
+
model = class_name.safe_constantize
|
8
|
+
abort "Could not find class: #{class_name}" unless model
|
9
|
+
abort "#{class_name} is not a searchkick model" unless Searchkick.models.include?(model)
|
10
|
+
|
11
|
+
puts "Reindexing #{model.name}..."
|
12
|
+
model.reindex
|
13
|
+
puts "Reindex successful"
|
14
14
|
end
|
15
15
|
|
16
16
|
namespace :reindex do
|
17
17
|
desc "reindex all models"
|
18
18
|
task all: :environment do
|
19
|
+
# eager load models to populate Searchkick.models
|
19
20
|
if Rails.respond_to?(:autoloaders) && Rails.autoloaders.zeitwerk_enabled?
|
20
21
|
# fix for https://github.com/rails/rails/issues/37006
|
21
22
|
Zeitwerk::Loader.eager_load_all
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: searchkick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -52,48 +52,6 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bundler
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rake
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
55
|
description:
|
98
56
|
email: andrew@chartkick.com
|
99
57
|
executables: []
|
@@ -101,7 +59,6 @@ extensions: []
|
|
101
59
|
extra_rdoc_files: []
|
102
60
|
files:
|
103
61
|
- CHANGELOG.md
|
104
|
-
- CONTRIBUTING.md
|
105
62
|
- LICENSE.txt
|
106
63
|
- README.md
|
107
64
|
- lib/searchkick.rb
|
@@ -145,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
102
|
- !ruby/object:Gem::Version
|
146
103
|
version: '0'
|
147
104
|
requirements: []
|
148
|
-
rubygems_version: 3.
|
105
|
+
rubygems_version: 3.1.2
|
149
106
|
signing_key:
|
150
107
|
specification_version: 4
|
151
108
|
summary: Intelligent search made easy with Rails and Elasticsearch
|
data/CONTRIBUTING.md
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# Contributing
|
2
|
-
|
3
|
-
First, thanks for wanting to contribute. You’re awesome! :heart:
|
4
|
-
|
5
|
-
## Help
|
6
|
-
|
7
|
-
We’re not able to provide support through GitHub Issues. If you’re looking for help with your code, try posting on [Stack Overflow](https://stackoverflow.com/).
|
8
|
-
|
9
|
-
All features should be documented. If you don’t see a feature in the docs, assume it doesn’t exist.
|
10
|
-
|
11
|
-
## Bugs
|
12
|
-
|
13
|
-
Think you’ve discovered a bug?
|
14
|
-
|
15
|
-
1. Search existing issues to see if it’s been reported.
|
16
|
-
2. Try the `master` branch to make sure it hasn’t been fixed.
|
17
|
-
|
18
|
-
```rb
|
19
|
-
gem "searchkick", github: "ankane/searchkick"
|
20
|
-
```
|
21
|
-
|
22
|
-
3. Try the `debug` option when searching. This can reveal useful info.
|
23
|
-
|
24
|
-
```ruby
|
25
|
-
Product.search("something", debug: true)
|
26
|
-
```
|
27
|
-
|
28
|
-
If the above steps don’t help, create an issue.
|
29
|
-
|
30
|
-
- Recreate the problem by forking [this gist](https://gist.github.com/ankane/f80b0923d9ae2c077f41997f7b704e5c). Include a link to your gist and the output in the issue.
|
31
|
-
- For exceptions, include the complete backtrace.
|
32
|
-
|
33
|
-
## New Features
|
34
|
-
|
35
|
-
If you’d like to discuss a new feature, create an issue and start the title with `[Idea]`.
|
36
|
-
|
37
|
-
## Pull Requests
|
38
|
-
|
39
|
-
Fork the project and create a pull request. A few tips:
|
40
|
-
|
41
|
-
- Keep changes to a minimum. If you have multiple features or fixes, submit multiple pull requests.
|
42
|
-
- Follow the existing style. The code should read like it’s written by a single person.
|
43
|
-
- Add one or more tests if possible. Make sure existing tests pass with:
|
44
|
-
|
45
|
-
```sh
|
46
|
-
bundle exec rake test
|
47
|
-
```
|
48
|
-
|
49
|
-
Feel free to open an issue to get feedback on your idea before spending too much time on it.
|
50
|
-
|
51
|
-
---
|
52
|
-
|
53
|
-
This contributing guide is released under [CCO](https://creativecommons.org/publicdomain/zero/1.0/) (public domain). Use it for your own project without attribution.
|