chewy 7.1.0 → 7.2.0
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/.github/workflows/ruby.yml +58 -0
- data/.rubocop.yml +13 -8
- data/.rubocop_todo.yml +110 -22
- data/CHANGELOG.md +53 -0
- data/Gemfile +0 -7
- data/Guardfile +3 -1
- data/README.md +282 -245
- data/chewy.gemspec +3 -5
- data/gemfiles/rails.5.2.activerecord.gemfile +8 -14
- data/gemfiles/rails.6.0.activerecord.gemfile +8 -14
- data/gemfiles/rails.6.1.activerecord.gemfile +8 -14
- data/lib/chewy.rb +21 -75
- data/lib/chewy/config.rb +40 -40
- data/lib/chewy/errors.rb +0 -12
- data/lib/chewy/fields/base.rb +11 -1
- data/lib/chewy/fields/root.rb +3 -4
- data/lib/chewy/index.rb +46 -87
- data/lib/chewy/index/actions.rb +51 -32
- data/lib/chewy/{type → index}/adapter/active_record.rb +12 -3
- data/lib/chewy/{type → index}/adapter/base.rb +2 -3
- data/lib/chewy/{type → index}/adapter/object.rb +27 -31
- data/lib/chewy/{type → index}/adapter/orm.rb +11 -14
- data/lib/chewy/{type → index}/crutch.rb +5 -5
- data/lib/chewy/{type → index}/import.rb +36 -27
- data/lib/chewy/{type → index}/import/bulk_builder.rb +15 -13
- data/lib/chewy/{type → index}/import/bulk_request.rb +6 -6
- data/lib/chewy/{type → index}/import/journal_builder.rb +10 -10
- data/lib/chewy/{type → index}/import/routine.rb +15 -14
- data/lib/chewy/{type → index}/mapping.rb +26 -31
- data/lib/chewy/{type → index}/observe.rb +9 -19
- data/lib/chewy/index/specification.rb +1 -0
- data/lib/chewy/{type → index}/syncer.rb +60 -57
- data/lib/chewy/{type → index}/witchcraft.rb +11 -7
- data/lib/chewy/{type → index}/wrapper.rb +2 -2
- data/lib/chewy/journal.rb +8 -8
- data/lib/chewy/minitest/helpers.rb +9 -13
- data/lib/chewy/minitest/search_index_receiver.rb +22 -26
- data/lib/chewy/railtie.rb +4 -2
- data/lib/chewy/rake_helper.rb +82 -107
- data/lib/chewy/rspec/update_index.rb +47 -43
- data/lib/chewy/search.rb +4 -17
- data/lib/chewy/search/loader.rb +18 -30
- data/lib/chewy/search/parameters.rb +4 -2
- data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
- data/lib/chewy/search/parameters/source.rb +5 -1
- data/lib/chewy/search/query_proxy.rb +9 -2
- data/lib/chewy/search/request.rb +82 -86
- data/lib/chewy/search/response.rb +4 -4
- data/lib/chewy/search/scoping.rb +6 -7
- data/lib/chewy/search/scrolling.rb +11 -11
- data/lib/chewy/stash.rb +14 -22
- data/lib/chewy/strategy.rb +3 -19
- data/lib/chewy/strategy/sidekiq.rb +1 -0
- data/lib/chewy/version.rb +1 -1
- data/lib/generators/chewy/install_generator.rb +1 -1
- data/lib/tasks/chewy.rake +10 -22
- data/migration_guide.md +14 -0
- data/spec/chewy/config_spec.rb +14 -39
- data/spec/chewy/fields/base_spec.rb +412 -148
- data/spec/chewy/fields/root_spec.rb +16 -24
- data/spec/chewy/fields/time_fields_spec.rb +5 -5
- data/spec/chewy/index/actions_spec.rb +270 -24
- data/spec/chewy/{type → index}/adapter/active_record_spec.rb +68 -40
- data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
- data/spec/chewy/{type → index}/import/bulk_builder_spec.rb +23 -31
- data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -6
- data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -15
- data/spec/chewy/{type → index}/import/routine_spec.rb +16 -16
- data/spec/chewy/{type → index}/import_spec.rb +102 -98
- data/spec/chewy/{type → index}/mapping_spec.rb +46 -54
- data/spec/chewy/index/observe_spec.rb +116 -0
- data/spec/chewy/index/settings_spec.rb +3 -1
- data/spec/chewy/index/specification_spec.rb +7 -17
- data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
- data/spec/chewy/{type → index}/witchcraft_spec.rb +20 -22
- data/spec/chewy/index/wrapper_spec.rb +100 -0
- data/spec/chewy/index_spec.rb +59 -102
- data/spec/chewy/journal_spec.rb +9 -22
- data/spec/chewy/minitest/helpers_spec.rb +13 -15
- data/spec/chewy/minitest/search_index_receiver_spec.rb +22 -26
- data/spec/chewy/multi_search_spec.rb +4 -5
- data/spec/chewy/rake_helper_spec.rb +145 -55
- data/spec/chewy/rspec/update_index_spec.rb +74 -71
- data/spec/chewy/search/loader_spec.rb +19 -37
- data/spec/chewy/search/pagination/kaminari_examples.rb +3 -5
- data/spec/chewy/search/pagination/kaminari_spec.rb +1 -1
- data/spec/chewy/search/parameters/indices_spec.rb +2 -8
- data/spec/chewy/search/parameters/order_spec.rb +1 -1
- data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
- data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
- data/spec/chewy/search/parameters/source_spec.rb +8 -2
- data/spec/chewy/search/parameters_spec.rb +12 -3
- data/spec/chewy/search/query_proxy_spec.rb +68 -17
- data/spec/chewy/search/request_spec.rb +222 -74
- data/spec/chewy/search/response_spec.rb +12 -12
- data/spec/chewy/search/scrolling_spec.rb +7 -9
- data/spec/chewy/search_spec.rb +32 -35
- data/spec/chewy/stash_spec.rb +9 -21
- data/spec/chewy/strategy/active_job_spec.rb +8 -8
- data/spec/chewy/strategy/atomic_spec.rb +9 -10
- data/spec/chewy/strategy/sidekiq_spec.rb +8 -8
- data/spec/chewy/strategy_spec.rb +19 -15
- data/spec/chewy_spec.rb +14 -100
- data/spec/spec_helper.rb +2 -21
- data/spec/support/active_record.rb +15 -5
- metadata +44 -103
- data/.circleci/config.yml +0 -214
- data/Appraisals +0 -81
- data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
- data/gemfiles/sequel.4.45.gemfile +0 -11
- data/lib/chewy/search/pagination/will_paginate.rb +0 -43
- data/lib/chewy/strategy/resque.rb +0 -27
- data/lib/chewy/strategy/shoryuken.rb +0 -40
- data/lib/chewy/type.rb +0 -120
- data/lib/chewy/type/actions.rb +0 -43
- data/lib/chewy/type/adapter/mongoid.rb +0 -67
- data/lib/chewy/type/adapter/sequel.rb +0 -93
- data/lib/sequel/plugins/chewy_observe.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
- data/spec/chewy/strategy/resque_spec.rb +0 -46
- data/spec/chewy/strategy/shoryuken_spec.rb +0 -70
- data/spec/chewy/type/actions_spec.rb +0 -50
- data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
- data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
- data/spec/chewy/type/observe_spec.rb +0 -137
- data/spec/chewy/type/wrapper_spec.rb +0 -100
- data/spec/chewy/type_spec.rb +0 -55
- data/spec/support/mongoid.rb +0 -93
- data/spec/support/sequel.rb +0 -80
|
@@ -2,25 +2,25 @@ require 'i18n/core_ext/hash'
|
|
|
2
2
|
|
|
3
3
|
# Rspec matcher `update_index`
|
|
4
4
|
# To use it - add `require 'chewy/rspec'` to the `spec_helper.rb`
|
|
5
|
-
# Simple usage - just pass
|
|
5
|
+
# Simple usage - just pass index as argument.
|
|
6
6
|
#
|
|
7
|
-
# specify { expect { user.save! }.to update_index(UsersIndex
|
|
8
|
-
# specify { expect { user.save! }.to update_index('users
|
|
9
|
-
# specify { expect { user.save! }.not_to update_index('users
|
|
7
|
+
# specify { expect { user.save! }.to update_index(UsersIndex) }
|
|
8
|
+
# specify { expect { user.save! }.to update_index('users') }
|
|
9
|
+
# specify { expect { user.save! }.not_to update_index('users') }
|
|
10
10
|
#
|
|
11
11
|
# This example will pass as well because user1 was reindexed
|
|
12
12
|
# and nothing was said about user2:
|
|
13
13
|
#
|
|
14
14
|
# specify { expect { [user1, user2].map(&:save!) }
|
|
15
|
-
# .to update_index(UsersIndex
|
|
15
|
+
# .to update_index(UsersIndex).and_reindex(user1) }
|
|
16
16
|
#
|
|
17
17
|
# If you need to specify reindexed records strictly - use `only` chain.
|
|
18
18
|
# Combined matcher chain methods:
|
|
19
19
|
#
|
|
20
20
|
# specify { expect { user1.destroy!; user2.save! } }
|
|
21
|
-
# .to update_index(UsersIndex
|
|
21
|
+
# .to update_index(UsersIndex).and_reindex(user2).and_delete(user1) }
|
|
22
22
|
#
|
|
23
|
-
RSpec::Matchers.define :update_index do |
|
|
23
|
+
RSpec::Matchers.define :update_index do |index_name, options = {}| # rubocop:disable Metrics/BlockLength
|
|
24
24
|
if !respond_to?(:failure_message) && respond_to?(:failure_message_for_should)
|
|
25
25
|
alias_method :failure_message, :failure_message_for_should
|
|
26
26
|
alias_method :failure_message_when_negated, :failure_message_for_should_not
|
|
@@ -28,30 +28,30 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
28
28
|
|
|
29
29
|
# Specify indexed records by passing record itself or id.
|
|
30
30
|
#
|
|
31
|
-
# specify { expect { user.save! }.to update_index(UsersIndex
|
|
32
|
-
# specify { expect { user.save! }.to update_index(UsersIndex
|
|
31
|
+
# specify { expect { user.save! }.to update_index(UsersIndex).and_reindex(user)
|
|
32
|
+
# specify { expect { user.save! }.to update_index(UsersIndex).and_reindex(42)
|
|
33
33
|
# specify { expect { [user1, user2].map(&:save!) }
|
|
34
|
-
# .to update_index(UsersIndex
|
|
34
|
+
# .to update_index(UsersIndex).and_reindex(user1, user2) }
|
|
35
35
|
# specify { expect { [user1, user2].map(&:save!) }
|
|
36
|
-
# .to update_index(UsersIndex
|
|
36
|
+
# .to update_index(UsersIndex).and_reindex(user1).and_reindex(user2) }
|
|
37
37
|
#
|
|
38
38
|
# Specify indexing count for every particular record. Useful in case
|
|
39
39
|
# urgent index updates.
|
|
40
40
|
#
|
|
41
41
|
# specify { expect { 2.times { user.save! } }
|
|
42
|
-
# .to update_index(UsersIndex
|
|
42
|
+
# .to update_index(UsersIndex).and_reindex(user, times: 2) }
|
|
43
43
|
#
|
|
44
44
|
# Specify reindexed attributes. Note that arrays are
|
|
45
45
|
# compared position-independently.
|
|
46
46
|
#
|
|
47
47
|
# specify { expect { user.update_attributes!(name: 'Duke') }
|
|
48
|
-
# .to update_index(UsersIndex
|
|
48
|
+
# .to update_index(UsersIndex).and_reindex(user, with: {name: 'Duke'}) }
|
|
49
49
|
#
|
|
50
50
|
# You can combine all the options and chain `and_reindex` method to
|
|
51
51
|
# specify options for every indexed record:
|
|
52
52
|
#
|
|
53
53
|
# specify { expect { 2.times { [user1, user2].map { |u| u.update_attributes!(name: "Duke#{u.id}") } } }
|
|
54
|
-
# .to update_index(UsersIndex
|
|
54
|
+
# .to update_index(UsersIndex)
|
|
55
55
|
# .and_reindex(user1, with: {name: 'Duke42'}) }
|
|
56
56
|
# .and_reindex(user2, times: 1, with: {name: 'Duke43'}) }
|
|
57
57
|
#
|
|
@@ -62,8 +62,8 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
62
62
|
|
|
63
63
|
# Specify deleted records with record itself or id passed.
|
|
64
64
|
#
|
|
65
|
-
# specify { expect { user.destroy! }.to update_index(UsersIndex
|
|
66
|
-
# specify { expect { user.destroy! }.to update_index(UsersIndex
|
|
65
|
+
# specify { expect { user.destroy! }.to update_index(UsersIndex).and_delete(user) }
|
|
66
|
+
# specify { expect { user.destroy! }.to update_index(UsersIndex).and_delete(user.id) }
|
|
67
67
|
#
|
|
68
68
|
chain(:and_delete) do |*args|
|
|
69
69
|
@delete ||= {}
|
|
@@ -73,14 +73,14 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
73
73
|
# Used for specifying than no other records would be indexed or deleted:
|
|
74
74
|
#
|
|
75
75
|
# specify { expect { [user1, user2].map(&:save!) }
|
|
76
|
-
# .to update_index(UsersIndex
|
|
76
|
+
# .to update_index(UsersIndex).and_reindex(user1, user2).only }
|
|
77
77
|
# specify { expect { [user1, user2].map(&:destroy!) }
|
|
78
|
-
# .to update_index(UsersIndex
|
|
78
|
+
# .to update_index(UsersIndex).and_delete(user1, user2).only }
|
|
79
79
|
#
|
|
80
80
|
# This example will fail:
|
|
81
81
|
#
|
|
82
82
|
# specify { expect { [user1, user2].map(&:save!) }
|
|
83
|
-
# .to update_index(UsersIndex
|
|
83
|
+
# .to update_index(UsersIndex).and_reindex(user1).only }
|
|
84
84
|
#
|
|
85
85
|
chain(:only) do |*_args|
|
|
86
86
|
raise 'Use `only` in conjunction with `and_reindex` or `and_delete`' if @reindex.blank? && @delete.blank?
|
|
@@ -92,19 +92,19 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
92
92
|
true
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
match do |block| # rubocop:disable BlockLength
|
|
95
|
+
match do |block| # rubocop:disable Metrics/BlockLength
|
|
96
96
|
@reindex ||= {}
|
|
97
97
|
@delete ||= {}
|
|
98
98
|
@missed_reindex = []
|
|
99
99
|
@missed_delete = []
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
index = Chewy.derive_name(index_name)
|
|
102
102
|
if defined?(Mocha) && RSpec.configuration.mock_framework.to_s == 'RSpec::Core::MockingAdapters::Mocha'
|
|
103
|
-
Chewy::
|
|
103
|
+
Chewy::Index::Import::BulkRequest.stubs(:new).with(index, any_parameters).returns(mock_bulk_request)
|
|
104
104
|
else
|
|
105
|
-
mocked_already = ::RSpec::Mocks.space.proxy_for(Chewy::
|
|
106
|
-
allow(Chewy::
|
|
107
|
-
allow(Chewy::
|
|
105
|
+
mocked_already = ::RSpec::Mocks.space.proxy_for(Chewy::Index::Import::BulkRequest).method_double_if_exists_for_message(:new)
|
|
106
|
+
allow(Chewy::Index::Import::BulkRequest).to receive(:new).and_call_original unless mocked_already
|
|
107
|
+
allow(Chewy::Index::Import::BulkRequest).to receive(:new).with(index, any_args).and_return(mock_bulk_request)
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
Chewy.strategy(options[:strategy] || :atomic) { block.call }
|
|
@@ -127,13 +127,13 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
@reindex.each_value do |document|
|
|
130
|
-
document[:match_count] = (!document[:expected_count] && document[:real_count]
|
|
130
|
+
document[:match_count] = (!document[:expected_count] && (document[:real_count]).positive?) ||
|
|
131
131
|
(document[:expected_count] && document[:expected_count] == document[:real_count])
|
|
132
132
|
document[:match_attributes] = document[:expected_attributes].blank? ||
|
|
133
133
|
compare_attributes(document[:expected_attributes], document[:real_attributes])
|
|
134
134
|
end
|
|
135
135
|
@delete.each_value do |document|
|
|
136
|
-
document[:match_count] = (!document[:expected_count] && document[:real_count]
|
|
136
|
+
document[:match_count] = (!document[:expected_count] && (document[:real_count]).positive?) ||
|
|
137
137
|
(document[:expected_count] && document[:expected_count] == document[:real_count])
|
|
138
138
|
end
|
|
139
139
|
|
|
@@ -142,13 +142,13 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
142
142
|
@delete.all? { |_, document| document[:match_count] }
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
failure_message do # rubocop:disable BlockLength
|
|
145
|
+
failure_message do # rubocop:disable Metrics/BlockLength
|
|
146
146
|
output = ''
|
|
147
147
|
|
|
148
148
|
if mock_bulk_request.updates.none?
|
|
149
|
-
output << "Expected index `#{
|
|
149
|
+
output << "Expected index `#{index_name}` to be updated, but it was not\n"
|
|
150
150
|
elsif @missed_reindex.present? || @missed_delete.present?
|
|
151
|
-
message = "Expected index `#{
|
|
151
|
+
message = "Expected index `#{index_name}` "
|
|
152
152
|
message << [
|
|
153
153
|
("to update documents #{@reindex.keys}" if @reindex.present?),
|
|
154
154
|
("to delete documents #{@delete.keys}" if @delete.present?)
|
|
@@ -166,9 +166,13 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
166
166
|
output << @reindex.each.with_object('') do |(id, document), result|
|
|
167
167
|
unless document[:match_count] && document[:match_attributes]
|
|
168
168
|
result << "Expected document with id `#{id}` to be reindexed"
|
|
169
|
-
if document[:real_count]
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
if (document[:real_count]).positive?
|
|
170
|
+
if document[:expected_count] && !document[:match_count]
|
|
171
|
+
result << "\n #{document[:expected_count]} times, but was reindexed #{document[:real_count]} times"
|
|
172
|
+
end
|
|
173
|
+
if document[:expected_attributes].present? && !document[:match_attributes]
|
|
174
|
+
result << "\n with #{document[:expected_attributes]}, but it was reindexed with #{document[:real_attributes]}"
|
|
175
|
+
end
|
|
172
176
|
else
|
|
173
177
|
result << ', but it was not'
|
|
174
178
|
end
|
|
@@ -179,11 +183,11 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
179
183
|
output << @delete.each.with_object('') do |(id, document), result|
|
|
180
184
|
unless document[:match_count]
|
|
181
185
|
result << "Expected document with id `#{id}` to be deleted"
|
|
182
|
-
result << if document[:real_count]
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
result << if (document[:real_count]).positive? && document[:expected_count]
|
|
187
|
+
"\n #{document[:expected_count]} times, but was deleted #{document[:real_count]} times"
|
|
188
|
+
else
|
|
189
|
+
', but it was not'
|
|
190
|
+
end
|
|
187
191
|
result << "\n"
|
|
188
192
|
end
|
|
189
193
|
end
|
|
@@ -193,9 +197,9 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
193
197
|
|
|
194
198
|
failure_message_when_negated do
|
|
195
199
|
if mock_bulk_request.updates.present?
|
|
196
|
-
"Expected index `#{
|
|
197
|
-
|
|
198
|
-
|
|
200
|
+
"Expected index `#{index_name}` not to be updated, but it was with #{mock_bulk_request.updates.map(&:values).flatten.group_by { |documents| documents[:_id] }.map do |id, documents|
|
|
201
|
+
"\n document id `#{id}` (#{documents.count} times)"
|
|
202
|
+
end.join}\n"
|
|
199
203
|
end
|
|
200
204
|
end
|
|
201
205
|
|
|
@@ -209,7 +213,7 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
209
213
|
expected_count = options[:times] || options[:count]
|
|
210
214
|
expected_attributes = (options[:with] || options[:attributes] || {}).deep_symbolize_keys
|
|
211
215
|
|
|
212
|
-
|
|
216
|
+
args.flatten.map do |document|
|
|
213
217
|
id = document.respond_to?(:id) ? document.id.to_s : document.to_s
|
|
214
218
|
[id, {
|
|
215
219
|
document: document,
|
|
@@ -218,7 +222,7 @@ RSpec::Matchers.define :update_index do |type_name, options = {}| # rubocop:disa
|
|
|
218
222
|
real_count: 0,
|
|
219
223
|
real_attributes: {}
|
|
220
224
|
}]
|
|
221
|
-
end
|
|
225
|
+
end.to_h
|
|
222
226
|
end
|
|
223
227
|
|
|
224
228
|
def compare_attributes(expected, real)
|
data/lib/chewy/search.rb
CHANGED
|
@@ -6,29 +6,22 @@ require 'chewy/search/response'
|
|
|
6
6
|
require 'chewy/search/loader'
|
|
7
7
|
require 'chewy/search/request'
|
|
8
8
|
require 'chewy/search/pagination/kaminari'
|
|
9
|
-
require 'chewy/search/pagination/will_paginate'
|
|
10
9
|
|
|
11
10
|
module Chewy
|
|
12
11
|
# This module being included to any provides an interface to the
|
|
13
|
-
# request DSL. By default it is included to {Chewy::Index}
|
|
14
|
-
# {Chewy::Type}.
|
|
12
|
+
# request DSL. By default it is included to {Chewy::Index}.
|
|
15
13
|
#
|
|
16
14
|
# The class used as a request DSL provider is
|
|
17
15
|
# inherited from {Chewy::Search::Request}
|
|
18
16
|
#
|
|
19
|
-
# Also, the search class is refined with
|
|
20
|
-
# providing modules: {Chewy::Search::Pagination::Kaminari} or
|
|
21
|
-
# {Chewy::Search::Pagination::WillPaginate}.
|
|
17
|
+
# Also, the search class is refined with the pagination module {Chewy::Search::Pagination::Kaminari}.
|
|
22
18
|
#
|
|
23
19
|
# @example
|
|
24
20
|
# PlacesIndex.query(match: {name: 'Moscow'})
|
|
25
|
-
# PlacesIndex::City.query(match: {name: 'Moscow'})
|
|
26
21
|
# @see Chewy::Index
|
|
27
|
-
# @see Chewy::Type
|
|
28
22
|
# @see Chewy::Search::Request
|
|
29
23
|
# @see Chewy::Search::ClassMethods
|
|
30
24
|
# @see Chewy::Search::Pagination::Kaminari
|
|
31
|
-
# @see Chewy::Search::Pagination::WillPaginate
|
|
32
25
|
module Search
|
|
33
26
|
extend ActiveSupport::Concern
|
|
34
27
|
|
|
@@ -55,15 +48,14 @@ module Chewy
|
|
|
55
48
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
|
|
56
49
|
# @return [Hash] the request result
|
|
57
50
|
def search_string(query, options = {})
|
|
58
|
-
options = options.merge(all.render.slice(:index
|
|
51
|
+
options = options.merge(all.render.slice(:index).merge(q: query))
|
|
59
52
|
Chewy.client.search(options)
|
|
60
53
|
end
|
|
61
54
|
|
|
62
|
-
# Delegates methods from the request class to the index
|
|
55
|
+
# Delegates methods from the request class to the index class
|
|
63
56
|
#
|
|
64
57
|
# @example
|
|
65
58
|
# PlacesIndex.query(match: {name: 'Moscow'})
|
|
66
|
-
# PlacesIndex::City.query(match: {name: 'Moscow'})
|
|
67
59
|
def method_missing(name, *args, &block)
|
|
68
60
|
if search_class::DELEGATED_METHODS.include?(name)
|
|
69
61
|
all.send(name, *args, &block)
|
|
@@ -85,11 +77,6 @@ module Chewy
|
|
|
85
77
|
def build_search_class(base)
|
|
86
78
|
search_class = Class.new(base)
|
|
87
79
|
|
|
88
|
-
if self < Chewy::Type
|
|
89
|
-
index_scopes = index.scopes - scopes
|
|
90
|
-
delegate_scoped index, search_class, index_scopes
|
|
91
|
-
end
|
|
92
|
-
|
|
93
80
|
delegate_scoped self, search_class, scopes
|
|
94
81
|
const_set('Query', search_class)
|
|
95
82
|
end
|
data/lib/chewy/search/loader.rb
CHANGED
|
@@ -3,32 +3,28 @@ module Chewy
|
|
|
3
3
|
# This class is used for two different purposes: load ORM/ODM
|
|
4
4
|
# source objects.
|
|
5
5
|
#
|
|
6
|
-
# @see Chewy::
|
|
6
|
+
# @see Chewy::Index::Import
|
|
7
7
|
# @see Chewy::Search::Request#load
|
|
8
8
|
# @see Chewy::Search::Response#objects
|
|
9
9
|
# @see Chewy::Search::Scrolling#scroll_objects
|
|
10
10
|
class Loader
|
|
11
|
-
# @param indexes [Array<Chewy::Index>] list of indexes to lookup
|
|
11
|
+
# @param indexes [Array<Chewy::Index>] list of indexes to lookup
|
|
12
12
|
# @param options [Hash] adapter-specific load options
|
|
13
|
-
# @see Chewy::
|
|
13
|
+
# @see Chewy::Index::Adapter::Base#load
|
|
14
14
|
def initialize(indexes: [], **options)
|
|
15
15
|
@indexes = indexes
|
|
16
16
|
@options = options
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
index_class = derive_index(index)
|
|
29
|
-
raise Chewy::UnderivableType, "Can not find index named `#{index}`" unless index_class
|
|
30
|
-
index_class.type_hash.values.first
|
|
31
|
-
end
|
|
19
|
+
def derive_index(index_name)
|
|
20
|
+
index = (@derive_index ||= {})[index_name] ||= indexes_hash[index_name] ||
|
|
21
|
+
indexes_hash[indexes_hash.keys.sort_by(&:length)
|
|
22
|
+
.reverse.detect do |name|
|
|
23
|
+
index_name.match(/#{name}(_.+|\z)/)
|
|
24
|
+
end]
|
|
25
|
+
raise Chewy::UndefinedIndex, "Can not find index named `#{index}`" unless index
|
|
26
|
+
|
|
27
|
+
index
|
|
32
28
|
end
|
|
33
29
|
|
|
34
30
|
# For each passed hit this method loads an ORM/ORD source object
|
|
@@ -37,17 +33,17 @@ module Chewy
|
|
|
37
33
|
# will be returned at the corresponding position in array.
|
|
38
34
|
#
|
|
39
35
|
# Records/documents are loaded in an efficient manner, performing
|
|
40
|
-
# a single query for each
|
|
36
|
+
# a single query for each index present.
|
|
41
37
|
#
|
|
42
38
|
# @param hits [Array<Hash>] ES hits array
|
|
43
39
|
# @return [Array<Object, nil>] the array of corresponding ORM/ODM objects
|
|
44
40
|
def load(hits)
|
|
45
|
-
hit_groups = hits.group_by { |hit|
|
|
46
|
-
loaded_objects = hit_groups.each_with_object({}) do |(
|
|
47
|
-
|
|
41
|
+
hit_groups = hits.group_by { |hit| hit['_index'] }
|
|
42
|
+
loaded_objects = hit_groups.each_with_object({}) do |(index_name, hit_group), result|
|
|
43
|
+
index = derive_index(index_name)
|
|
48
44
|
ids = hit_group.map { |hit| hit['_id'] }
|
|
49
|
-
loaded =
|
|
50
|
-
loaded ||= hit_group.map { |hit|
|
|
45
|
+
loaded = index.adapter.load(ids, **@options.merge(_index: index.base_name))
|
|
46
|
+
loaded ||= hit_group.map { |hit| index.build(hit) }
|
|
51
47
|
|
|
52
48
|
result.merge!(hit_group.zip(loaded).to_h)
|
|
53
49
|
end
|
|
@@ -57,14 +53,6 @@ module Chewy
|
|
|
57
53
|
|
|
58
54
|
private
|
|
59
55
|
|
|
60
|
-
def derive_index(index_name)
|
|
61
|
-
(@derive_index ||= {})[index_name] ||= indexes_hash[index_name] ||
|
|
62
|
-
indexes_hash[indexes_hash.keys.sort_by(&:length)
|
|
63
|
-
.reverse.detect do |name|
|
|
64
|
-
index_name.match(/#{name}(_.+|\z)/)
|
|
65
|
-
end]
|
|
66
|
-
end
|
|
67
|
-
|
|
68
56
|
def indexes_hash
|
|
69
57
|
@indexes_hash ||= @indexes.index_by(&:index_name)
|
|
70
58
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'parameters', 'concerns', '*.rb')) { |f| require f }
|
|
2
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'parameters', '*.rb')) { |f| require f }
|
|
1
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'parameters', 'concerns', '*.rb')).sort.each { |f| require f }
|
|
2
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'parameters', '*.rb')).sort.each { |f| require f }
|
|
3
3
|
|
|
4
4
|
module Chewy
|
|
5
5
|
module Search
|
|
@@ -24,6 +24,7 @@ module Chewy
|
|
|
24
24
|
|
|
25
25
|
# @return [{Symbol => Chewy::Search::Parameters::Storage}]
|
|
26
26
|
attr_accessor :storages
|
|
27
|
+
|
|
27
28
|
delegate :[], :[]=, to: :storages
|
|
28
29
|
|
|
29
30
|
# Accepts an initial hash as basic values or parameter storages.
|
|
@@ -120,6 +121,7 @@ module Chewy
|
|
|
120
121
|
|
|
121
122
|
def assert_storages(names)
|
|
122
123
|
raise ArgumentError, 'No storage names were specified' if names.empty?
|
|
124
|
+
|
|
123
125
|
names = names.map(&:to_sym)
|
|
124
126
|
self.class.storages.values_at(*names)
|
|
125
127
|
names
|
|
@@ -5,7 +5,7 @@ module Chewy
|
|
|
5
5
|
class Parameters
|
|
6
6
|
# This is a basic storage implementation for `query`, `filter`
|
|
7
7
|
# and `post_filter` storages. It uses `bool` query as a root
|
|
8
|
-
# structure for each of them. The `bool` root is
|
|
8
|
+
# structure for each of them. The `bool` root is omitted on
|
|
9
9
|
# rendering if there is only a single query in the `must` or
|
|
10
10
|
# `should` array. Besides the standard parameter storage
|
|
11
11
|
# capabilities, it provides specialized methods for the `bool`
|
|
@@ -86,7 +86,7 @@ module Chewy
|
|
|
86
86
|
def reduce
|
|
87
87
|
value = to_h
|
|
88
88
|
.reject { |_, v| v.blank? }
|
|
89
|
-
.
|
|
89
|
+
.transform_values { |v| v.is_a?(Array) && v.one? ? v.first : v }
|
|
90
90
|
value.delete(:minimum_should_match) if should.empty?
|
|
91
91
|
value
|
|
92
92
|
end
|
|
@@ -17,7 +17,11 @@ module Chewy
|
|
|
17
17
|
# In case of hash, respective values are concatenated as well.
|
|
18
18
|
#
|
|
19
19
|
# @see Chewy::Search::Parameters::Storage#update!
|
|
20
|
-
# @param other_value
|
|
20
|
+
# @param other_value
|
|
21
|
+
# [true, false, {
|
|
22
|
+
# Symbol => Array<String, Symbol>, String, Symbol},
|
|
23
|
+
# Array<String, Symbol>, String, Symbol
|
|
24
|
+
# ] any acceptable storage value
|
|
21
25
|
# @return [{Symbol => Array<String>, true, false}] updated value
|
|
22
26
|
def update!(other_value)
|
|
23
27
|
new_value = normalize(other_value)
|
|
@@ -102,6 +102,7 @@ module Chewy
|
|
|
102
102
|
%i[must should must_not].each do |method|
|
|
103
103
|
define_method method do |query_hash = nil, &block|
|
|
104
104
|
raise ArgumentError, "Please provide a parameter or a block to `#{method}`" unless query_hash || block
|
|
105
|
+
|
|
105
106
|
@request.send(:modify, @parameter_name) { send(method, block || query_hash) }
|
|
106
107
|
end
|
|
107
108
|
end
|
|
@@ -237,8 +238,14 @@ module Chewy
|
|
|
237
238
|
# @yield the block is processed by `elasticsearch-dsl` gem
|
|
238
239
|
%i[and or not].each do |method|
|
|
239
240
|
define_method method do |query_hash_or_scope = nil, &block|
|
|
240
|
-
|
|
241
|
-
|
|
241
|
+
unless query_hash_or_scope || block
|
|
242
|
+
raise ArgumentError,
|
|
243
|
+
"Please provide a parameter or a block to `#{method}`"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
if !block && query_hash_or_scope.is_a?(Chewy::Search::Request)
|
|
247
|
+
query_hash_or_scope = query_hash_or_scope.parameters[@parameter_name].value
|
|
248
|
+
end
|
|
242
249
|
@request.send(:modify, @parameter_name) { send(method, block || query_hash_or_scope) }
|
|
243
250
|
end
|
|
244
251
|
end
|
data/lib/chewy/search/request.rb
CHANGED
|
@@ -8,11 +8,11 @@ module Chewy
|
|
|
8
8
|
# @see Chewy::Search
|
|
9
9
|
# @example
|
|
10
10
|
# scope = Chewy::Search::Request.new(PlacesIndex)
|
|
11
|
-
# # => <Chewy::Search::Request {:index=>["places"], :
|
|
11
|
+
# # => <Chewy::Search::Request {:index=>["places"], :body=>{}}>
|
|
12
12
|
# scope.limit(20)
|
|
13
|
-
# # => <Chewy::Search::Request {:index=>["places"], :
|
|
13
|
+
# # => <Chewy::Search::Request {:index=>["places"], :body=>{:size=>20}}>
|
|
14
14
|
# scope.order(:name).offset(10)
|
|
15
|
-
# # => <Chewy::Search::Request {:index=>["places"], :
|
|
15
|
+
# # => <Chewy::Search::Request {:index=>["places"], :body=>{:sort=>["name"], :from=>10}}>
|
|
16
16
|
class Request
|
|
17
17
|
include Enumerable
|
|
18
18
|
include Scoping
|
|
@@ -45,40 +45,28 @@ module Chewy
|
|
|
45
45
|
].freeze
|
|
46
46
|
|
|
47
47
|
delegate :hits, :wrappers, :objects, :records, :documents,
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
:object_hash, :record_hash, :document_hash,
|
|
49
|
+
:total, :max_score, :took, :timed_out?, to: :response
|
|
50
50
|
delegate :each, :size, :to_a, :[], to: :wrappers
|
|
51
51
|
alias_method :to_ary, :to_a
|
|
52
52
|
alias_method :total_count, :total
|
|
53
53
|
alias_method :total_entries, :total
|
|
54
54
|
|
|
55
|
-
# The class is initialized with the list of chewy indexes
|
|
56
|
-
#
|
|
55
|
+
# The class is initialized with the list of chewy indexes,
|
|
56
|
+
# which are later used to compose requests.
|
|
57
57
|
# Any symbol/string passed is treated as an index identifier.
|
|
58
58
|
#
|
|
59
59
|
# @example
|
|
60
60
|
# Chewy::Search::Request.new(:places)
|
|
61
|
-
# # => <Chewy::Search::Request {:index=>["places"]}>
|
|
61
|
+
# # => <Chewy::Search::Request {:index=>["places"], :body=>{}}>
|
|
62
62
|
# Chewy::Search::Request.new(PlacesIndex)
|
|
63
|
-
# # => <Chewy::Search::Request {:index=>["places"]}>
|
|
64
|
-
# Chewy::Search::Request.new(PlacesIndex
|
|
65
|
-
# # => <Chewy::Search::Request {:index=>["places"]}>
|
|
66
|
-
#
|
|
67
|
-
|
|
68
|
-
# @param indexes_or_types [Array<Chewy::Index, Chewy::Type, String, Symbol>] indices and types in any combinations
|
|
69
|
-
def initialize(*indices_or_types)
|
|
70
|
-
indices = indices_or_types.reject do |klass|
|
|
71
|
-
klass.is_a?(Class) && klass < Chewy::Type
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
types = indices_or_types.select do |klass|
|
|
75
|
-
klass.is_a?(Class) && klass < Chewy::Type
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
indices += types.map(&:index)
|
|
79
|
-
|
|
63
|
+
# # => <Chewy::Search::Request {:index=>["places"], :body=>{}}>
|
|
64
|
+
# Chewy::Search::Request.new(UsersIndex, PlacesIndex)
|
|
65
|
+
# # => <Chewy::Search::Request {:index=>["users", "places"], :body=>{}}>
|
|
66
|
+
# @param indexes [Array<Chewy::Index, String, Symbol>] indexes
|
|
67
|
+
def initialize(*indexes)
|
|
80
68
|
parameters.modify!(:indices) do
|
|
81
|
-
replace!(indices:
|
|
69
|
+
replace!(indices: indexes)
|
|
82
70
|
end
|
|
83
71
|
end
|
|
84
72
|
|
|
@@ -140,17 +128,17 @@ module Chewy
|
|
|
140
128
|
"<#{self.class} #{render}>"
|
|
141
129
|
end
|
|
142
130
|
|
|
143
|
-
# @!group Chainable request
|
|
131
|
+
# @!group Chainable request modifications
|
|
144
132
|
|
|
145
133
|
# @!method query(query_hash=nil, &block)
|
|
146
|
-
# Adds `
|
|
134
|
+
# Adds `query` parameter to the search request body.
|
|
147
135
|
#
|
|
148
136
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-query.html
|
|
149
137
|
# @see Chewy::Search::Parameters::Query
|
|
150
138
|
# @return [Chewy::Search::Request, Chewy::Search::QueryProxy]
|
|
151
139
|
#
|
|
152
140
|
# @overload query(query_hash)
|
|
153
|
-
# If pure hash is passed it goes straight to the `
|
|
141
|
+
# If pure hash is passed it goes straight to the `query` parameter storage.
|
|
154
142
|
# Acts exactly the same way as {Chewy::Search::QueryProxy#must}.
|
|
155
143
|
#
|
|
156
144
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
|
|
@@ -169,7 +157,7 @@ module Chewy
|
|
|
169
157
|
# @example
|
|
170
158
|
# PlacesIndex.query { match name: 'Moscow' }
|
|
171
159
|
# # => <PlacesIndex::Query {..., :body=>{:query=>{:match=>{:name=>"Moscow"}}}}>
|
|
172
|
-
# @yield the block is processed by `elasticsearch-
|
|
160
|
+
# @yield the block is processed by `elasticsearch-dsl` gem
|
|
173
161
|
# @return [Chewy::Search::Request]
|
|
174
162
|
#
|
|
175
163
|
# @overload query
|
|
@@ -185,7 +173,7 @@ module Chewy
|
|
|
185
173
|
# @return [Chewy::Search::QueryProxy]
|
|
186
174
|
#
|
|
187
175
|
# @!method filter(query_hash=nil, &block)
|
|
188
|
-
# Adds `
|
|
176
|
+
# Adds `filter` context of the `query` parameter at the
|
|
189
177
|
# search request body.
|
|
190
178
|
#
|
|
191
179
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html
|
|
@@ -193,7 +181,7 @@ module Chewy
|
|
|
193
181
|
# @return [Chewy::Search::Request, Chewy::Search::QueryProxy]
|
|
194
182
|
#
|
|
195
183
|
# @overload filter(query_hash)
|
|
196
|
-
# If pure hash is passed it goes straight to the `
|
|
184
|
+
# If pure hash is passed it goes straight to the `filter` context of the `query` parameter storage.
|
|
197
185
|
# Acts exactly the same way as {Chewy::Search::QueryProxy#must}.
|
|
198
186
|
#
|
|
199
187
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
|
|
@@ -214,7 +202,7 @@ module Chewy
|
|
|
214
202
|
# PlacesIndex.filter { match name: 'Moscow' }
|
|
215
203
|
# # => <PlacesIndex::Query {..., :body=>{:query=>{:bool=>{
|
|
216
204
|
# # :filter=>{:match=>{:name=>"Moscow"}}}}}}>
|
|
217
|
-
# @yield the block is processed by `elasticsearch-
|
|
205
|
+
# @yield the block is processed by `elasticsearch-dsl` gem
|
|
218
206
|
# @return [Chewy::Search::Request]
|
|
219
207
|
#
|
|
220
208
|
# @overload filter
|
|
@@ -232,7 +220,7 @@ module Chewy
|
|
|
232
220
|
# @!method post_filter(query_hash=nil, &block)
|
|
233
221
|
# Adds `post_filter` parameter to the search request body.
|
|
234
222
|
#
|
|
235
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-
|
|
223
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/filter-search-results.html#post-filter
|
|
236
224
|
# @see Chewy::Search::Parameters::PostFilter
|
|
237
225
|
# @return [Chewy::Search::Request, Chewy::Search::QueryProxy]
|
|
238
226
|
#
|
|
@@ -256,7 +244,7 @@ module Chewy
|
|
|
256
244
|
# @example
|
|
257
245
|
# PlacesIndex.post_filter { match name: 'Moscow' }
|
|
258
246
|
# # => <PlacesIndex::Query {..., :body=>{:post_filter=>{:match=>{:name=>"Moscow"}}}}>
|
|
259
|
-
# @yield the block is processed by `elasticsearch-
|
|
247
|
+
# @yield the block is processed by `elasticsearch-dsl` gem
|
|
260
248
|
# @return [Chewy::Search::Request]
|
|
261
249
|
#
|
|
262
250
|
# @overload post_filter
|
|
@@ -287,7 +275,7 @@ module Chewy
|
|
|
287
275
|
# PlacesIndex.order(:name, population: {order: :asc}).order(:coordinates)
|
|
288
276
|
# # => <PlacesIndex::Query {..., :body=>{:sort=>["name", {"population"=>{:order=>:asc}}, "coordinates"]}}>
|
|
289
277
|
# @see Chewy::Search::Parameters::Order
|
|
290
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-
|
|
278
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html
|
|
291
279
|
# @param values [Array<Hash, String, Symbol>] sort fields and options
|
|
292
280
|
# @return [Chewy::Search::Request]
|
|
293
281
|
#
|
|
@@ -298,7 +286,7 @@ module Chewy
|
|
|
298
286
|
# PlacesIndex.docvalue_fields(:name).docvalue_fields(:population, :coordinates)
|
|
299
287
|
# # => <PlacesIndex::Query {..., :body=>{:docvalue_fields=>["name", "population", "coordinates"]}}>
|
|
300
288
|
# @see Chewy::Search::Parameters::DocvalueFields
|
|
301
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-
|
|
289
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#docvalue-fields
|
|
302
290
|
# @param values [Array<String, Symbol>] field names
|
|
303
291
|
# @return [Chewy::Search::Request]
|
|
304
292
|
%i[order docvalue_fields].each do |name|
|
|
@@ -328,7 +316,7 @@ module Chewy
|
|
|
328
316
|
# PlacesIndex.order(:name, population: {order: :asc}).reorder(:coordinates)
|
|
329
317
|
# # => <PlacesIndex::Query {..., :body=>{:sort=>["coordinates"]}}>
|
|
330
318
|
# @see Chewy::Search::Parameters::Order
|
|
331
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-
|
|
319
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html
|
|
332
320
|
# @param values [Array<Hash, String, Symbol>] sort fields and options
|
|
333
321
|
# @return [Chewy::Search::Request]
|
|
334
322
|
def reorder(value, *values)
|
|
@@ -342,9 +330,9 @@ module Chewy
|
|
|
342
330
|
# PlacesIndex.track_scores
|
|
343
331
|
# # => <PlacesIndex::Query {..., :body=>{:track_scores=>true}}>
|
|
344
332
|
# PlacesIndex.track_scores.track_scores(false)
|
|
345
|
-
# # => <PlacesIndex::Query {:index=>["places"]
|
|
333
|
+
# # => <PlacesIndex::Query {:index=>["places"]}>
|
|
346
334
|
# @see Chewy::Search::Parameters::TrackScores
|
|
347
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
335
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html#_track_scores
|
|
348
336
|
# @param value [true, false]
|
|
349
337
|
# @return [Chewy::Search::Request]
|
|
350
338
|
#
|
|
@@ -355,9 +343,9 @@ module Chewy
|
|
|
355
343
|
# PlacesIndex.explain
|
|
356
344
|
# # => <PlacesIndex::Query {..., :body=>{:explain=>true}}>
|
|
357
345
|
# PlacesIndex.explain.explain(false)
|
|
358
|
-
# # => <PlacesIndex::Query {:index=>["places"]
|
|
346
|
+
# # => <PlacesIndex::Query {:index=>["places"]}>
|
|
359
347
|
# @see Chewy::Search::Parameters::Explain
|
|
360
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
348
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-explain.html
|
|
361
349
|
# @param value [true, false]
|
|
362
350
|
# @return [Chewy::Search::Request]
|
|
363
351
|
#
|
|
@@ -368,9 +356,9 @@ module Chewy
|
|
|
368
356
|
# PlacesIndex.version
|
|
369
357
|
# # => <PlacesIndex::Query {..., :body=>{:version=>true}}>
|
|
370
358
|
# PlacesIndex.version.version(false)
|
|
371
|
-
# # => <PlacesIndex::Query {:index=>["places"]
|
|
359
|
+
# # => <PlacesIndex::Query {:index=>["places"]}>
|
|
372
360
|
# @see Chewy::Search::Parameters::Version
|
|
373
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
361
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
|
|
374
362
|
# @param value [true, false]
|
|
375
363
|
# @return [Chewy::Search::Request]
|
|
376
364
|
#
|
|
@@ -381,9 +369,9 @@ module Chewy
|
|
|
381
369
|
# PlacesIndex.profile
|
|
382
370
|
# # => <PlacesIndex::Query {..., :body=>{:profile=>true}}>
|
|
383
371
|
# PlacesIndex.profile.profile(false)
|
|
384
|
-
# # => <PlacesIndex::Query {:index=>["places"]
|
|
372
|
+
# # => <PlacesIndex::Query {:index=>["places"]}>
|
|
385
373
|
# @see Chewy::Search::Parameters::Profile
|
|
386
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
374
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-profile.html
|
|
387
375
|
# @param value [true, false]
|
|
388
376
|
# @return [Chewy::Search::Request]
|
|
389
377
|
#
|
|
@@ -417,7 +405,7 @@ module Chewy
|
|
|
417
405
|
# PlacesIndex.request_cache(false)
|
|
418
406
|
# # => <PlacesIndex::Query {..., :body=>{:request_cache=>false}}>
|
|
419
407
|
# @see Chewy::Search::Parameters::RequestCache
|
|
420
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
408
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/shard-request-cache.html#_enabling_and_disabling_caching_per_request
|
|
421
409
|
# @param value [true, false, nil]
|
|
422
410
|
# @return [Chewy::Search::Request]
|
|
423
411
|
#
|
|
@@ -428,7 +416,7 @@ module Chewy
|
|
|
428
416
|
# PlacesIndex.search_type(:dfs_query_then_fetch)
|
|
429
417
|
# # => <PlacesIndex::Query {..., :body=>{:search_type=>"dfs_query_then_fetch"}}>
|
|
430
418
|
# @see Chewy::Search::Parameters::SearchType
|
|
431
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
419
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html#search-type
|
|
432
420
|
# @param value [String, Symbol]
|
|
433
421
|
# @return [Chewy::Search::Request]
|
|
434
422
|
#
|
|
@@ -439,7 +427,7 @@ module Chewy
|
|
|
439
427
|
# PlacesIndex.preference(:_primary_first)
|
|
440
428
|
# # => <PlacesIndex::Query {..., :body=>{:preference=>"_primary_first"}}>
|
|
441
429
|
# @see Chewy::Search::Parameters::Preference
|
|
442
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
430
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html#search-preference
|
|
443
431
|
# @param value [String, Symbol]
|
|
444
432
|
# @return [Chewy::Search::Request]
|
|
445
433
|
#
|
|
@@ -450,7 +438,7 @@ module Chewy
|
|
|
450
438
|
# PlacesIndex.timeout('1m')
|
|
451
439
|
# <PlacesIndex::Query {..., :body=>{:timeout=>"1m"}}>
|
|
452
440
|
# @see Chewy::Search::Parameters::Timeout
|
|
453
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
441
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units
|
|
454
442
|
# @param value [String, Symbol]
|
|
455
443
|
# @return [Chewy::Search::Request]
|
|
456
444
|
#
|
|
@@ -461,7 +449,7 @@ module Chewy
|
|
|
461
449
|
# PlacesIndex.limit(10)
|
|
462
450
|
# <PlacesIndex::Query {..., :body=>{:size=>10}}>
|
|
463
451
|
# @see Chewy::Search::Parameters::Limit
|
|
464
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
452
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html
|
|
465
453
|
# @param value [String, Integer]
|
|
466
454
|
# @return [Chewy::Search::Request]
|
|
467
455
|
#
|
|
@@ -472,7 +460,7 @@ module Chewy
|
|
|
472
460
|
# PlacesIndex.offset(10)
|
|
473
461
|
# <PlacesIndex::Query {..., :body=>{:from=>10}}>
|
|
474
462
|
# @see Chewy::Search::Parameters::Offset
|
|
475
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
463
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html
|
|
476
464
|
# @param value [String, Integer]
|
|
477
465
|
# @return [Chewy::Search::Request]
|
|
478
466
|
#
|
|
@@ -483,7 +471,7 @@ module Chewy
|
|
|
483
471
|
# PlacesIndex.terminate_after(10)
|
|
484
472
|
# <PlacesIndex::Query {..., :body=>{:terminate_after=>10}}>
|
|
485
473
|
# @see Chewy::Search::Parameters::Offset
|
|
486
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
474
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.html#quickly-check-for-matching-docs
|
|
487
475
|
# @param value [String, Integer]
|
|
488
476
|
# @return [Chewy::Search::Request]
|
|
489
477
|
#
|
|
@@ -494,7 +482,7 @@ module Chewy
|
|
|
494
482
|
# PlacesIndex.min_score(2)
|
|
495
483
|
# <PlacesIndex::Query {..., :body=>{:min_score=>2.0}}>
|
|
496
484
|
# @see Chewy::Search::Parameters::Offset
|
|
497
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
485
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html#search-api-min-score
|
|
498
486
|
# @param value [String, Integer, Float]
|
|
499
487
|
# @return [Chewy::Search::Request]
|
|
500
488
|
%i[request_cache search_type preference timeout limit offset terminate_after min_score].each do |name|
|
|
@@ -506,7 +494,7 @@ module Chewy
|
|
|
506
494
|
# @!method source(*values)
|
|
507
495
|
# Updates `_source` request part. Accepts either an array
|
|
508
496
|
# of field names/templates or a hash with `includes` and `excludes`
|
|
509
|
-
# keys. Source also can be disabled
|
|
497
|
+
# keys. Source also can be disabled entirely or enabled again.
|
|
510
498
|
#
|
|
511
499
|
# @example
|
|
512
500
|
# PlacesIndex.source(:name).source(includes: [:popularity], excludes: :description)
|
|
@@ -514,13 +502,13 @@ module Chewy
|
|
|
514
502
|
# PlacesIndex.source(false)
|
|
515
503
|
# # => <PlacesIndex::Query {..., :body=>{:_source=>false}}>
|
|
516
504
|
# @see Chewy::Search::Parameters::Source
|
|
517
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
505
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#source-filtering
|
|
518
506
|
# @param values [true, false, {Symbol => Array<String, Symbol>, String, Symbol}, Array<String, Symbol>, String, Symbol]
|
|
519
507
|
# @return [Chewy::Search::Request]
|
|
520
508
|
#
|
|
521
509
|
# @!method stored_fields(*values)
|
|
522
510
|
# Updates `stored_fields` request part. Accepts an array of field
|
|
523
|
-
# names. Can be
|
|
511
|
+
# names. Can be entirely disabled and enabled back.
|
|
524
512
|
#
|
|
525
513
|
# @example
|
|
526
514
|
# PlacesIndex.stored_fields(:name).stored_fields(:description)
|
|
@@ -528,7 +516,7 @@ module Chewy
|
|
|
528
516
|
# PlacesIndex.stored_fields(false)
|
|
529
517
|
# # => <PlacesIndex::Query {..., :body=>{:stored_fields=>"_none_"}}>
|
|
530
518
|
# @see Chewy::Search::Parameters::StoredFields
|
|
531
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
519
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#stored-fields
|
|
532
520
|
# @param values [true, false, String, Symbol, Array<String, Symbol>]
|
|
533
521
|
# @return [Chewy::Search::Request]
|
|
534
522
|
%i[source stored_fields].each do |name|
|
|
@@ -544,7 +532,7 @@ module Chewy
|
|
|
544
532
|
# PlacesIndex.search_after(42, 'Moscow').search_after('London')
|
|
545
533
|
# # => <PlacesIndex::Query {..., :body=>{:search_after=>["London"]}}>
|
|
546
534
|
# @see Chewy::Search::Parameters::SearchAfter
|
|
547
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
535
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html#search-after
|
|
548
536
|
# @param value [Array, Object]
|
|
549
537
|
# @return [Chewy::Search::Request]
|
|
550
538
|
def search_after(value, *values)
|
|
@@ -552,9 +540,9 @@ module Chewy
|
|
|
552
540
|
end
|
|
553
541
|
|
|
554
542
|
# Stores ORM/ODM objects loading options. Options
|
|
555
|
-
# might be define per-
|
|
543
|
+
# might be define per-index or be global, depends on the adapter
|
|
556
544
|
# loading implementation. Also, there are 2 loading options to select
|
|
557
|
-
# or exclude
|
|
545
|
+
# or exclude indexes from loading: `only` and `except` respectively.
|
|
558
546
|
# Options are updated on further method calls.
|
|
559
547
|
#
|
|
560
548
|
# @example
|
|
@@ -579,7 +567,7 @@ module Chewy
|
|
|
579
567
|
# # "field1"=>{:script=>{:lang=>"painless", :inline=>"some script here"}},
|
|
580
568
|
# # "field2"=>{:script=>{:lang=>"painless", :inline=>"some script here"}}}}}>
|
|
581
569
|
# @see Chewy::Search::Parameters::ScriptFields
|
|
582
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
570
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#script-fields
|
|
583
571
|
# @param value [Hash]
|
|
584
572
|
# @return [Chewy::Search::Request]
|
|
585
573
|
#
|
|
@@ -591,7 +579,7 @@ module Chewy
|
|
|
591
579
|
# PlacesIndex.indices_boost(index1: 1.2, index2: 1.3).indices_boost(index1: 1.5)
|
|
592
580
|
# # => <PlacesIndex::Query {..., :body=>{:indices_boost=>[{"index2"=>1.3}, {"index1"=>1.5}]}}>
|
|
593
581
|
# @see Chewy::Search::Parameters::IndicesBoost
|
|
594
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
582
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multiple-indices.html#index-boost
|
|
595
583
|
# @param value [{String, Symbol => String, Integer, Float}]
|
|
596
584
|
# @return [Chewy::Search::Request]
|
|
597
585
|
#
|
|
@@ -603,7 +591,7 @@ module Chewy
|
|
|
603
591
|
# PlacesIndex.rescore(window_size: 100, query: {}).rescore(window_size: 200, query: {})
|
|
604
592
|
# # => <PlacesIndex::Query {..., :body=>{:rescore=>[{:window_size=>100, :query=>{}}, {:window_size=>200, :query=>{}}]}}>
|
|
605
593
|
# @see Chewy::Search::Parameters::Rescore
|
|
606
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
594
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/filter-search-results.html#rescore
|
|
607
595
|
# @param value [Hash, Array<Hash>]
|
|
608
596
|
# @return [Chewy::Search::Request]
|
|
609
597
|
#
|
|
@@ -619,7 +607,7 @@ module Chewy
|
|
|
619
607
|
# # "fields"=>{:description=>{:type=>"plain"}},
|
|
620
608
|
# # "pre_tags"=>["<em>"], "post_tags"=>["</em>"]}}}>
|
|
621
609
|
# @see Chewy::Search::Parameters::Highlight
|
|
622
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
610
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html
|
|
623
611
|
# @param value [Hash]
|
|
624
612
|
# @return [Chewy::Search::Request]
|
|
625
613
|
%i[script_fields indices_boost rescore highlight].each do |name|
|
|
@@ -642,7 +630,7 @@ module Chewy
|
|
|
642
630
|
# # "names"=>{:text=>"tring out Elasticsearch"},
|
|
643
631
|
# # "descriptions"=>{:text=>"some other text"}}}}>
|
|
644
632
|
# @see Chewy::Search::Parameters::Suggest
|
|
645
|
-
# @see https://www.elastic.co/guide/en/elasticsearch/reference/
|
|
633
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html
|
|
646
634
|
# @param value [Hash]
|
|
647
635
|
# @return [Chewy::Search::Request]
|
|
648
636
|
#
|
|
@@ -728,7 +716,10 @@ module Chewy
|
|
|
728
716
|
# scope1.and(scope2)
|
|
729
717
|
# # => <PlacesIndex::Query {..., :body=>{:query=>{:bool=>{
|
|
730
718
|
# # :must=>[{:match=>{:name=>"London"}}, {:match=>{:name=>"Washington"}}],
|
|
731
|
-
# # :filter=>{
|
|
719
|
+
# # :filter=>{
|
|
720
|
+
# # :bool=>{:must=>[{:term=>{:name=>"Moscow"}}, {:bool=>{:must_not=>{:term=>{:name=>"Berlin"}}}}]}
|
|
721
|
+
# # }
|
|
722
|
+
# # }}}}>
|
|
732
723
|
# @param other [Chewy::Search::Request] scope to merge
|
|
733
724
|
# @return [Chewy::Search::Request] new scope
|
|
734
725
|
#
|
|
@@ -745,7 +736,10 @@ module Chewy
|
|
|
745
736
|
# scope1.or(scope2)
|
|
746
737
|
# # => <PlacesIndex::Query {..., :body=>{:query=>{:bool=>{
|
|
747
738
|
# # :should=>[{:match=>{:name=>"London"}}, {:match=>{:name=>"Washington"}}],
|
|
748
|
-
# # :filter=>{
|
|
739
|
+
# # :filter=>{
|
|
740
|
+
# # :bool=>{:should=>[{:term=>{:name=>"Moscow"}}, {:bool=>{:must_not=>{:term=>{:name=>"Berlin"}}}}]}
|
|
741
|
+
# # }
|
|
742
|
+
# # }}}}>
|
|
749
743
|
# @param other [Chewy::Search::Request] scope to merge
|
|
750
744
|
# @return [Chewy::Search::Request] new scope
|
|
751
745
|
#
|
|
@@ -762,7 +756,13 @@ module Chewy
|
|
|
762
756
|
# scope1.not(scope2)
|
|
763
757
|
# # => <PlacesIndex::Query {..., :body=>{:query=>{:bool=>{
|
|
764
758
|
# # :must=>{:match=>{:name=>"London"}}, :must_not=>{:match=>{:name=>"Washington"}},
|
|
765
|
-
# # :filter=>{
|
|
759
|
+
# # :filter=>{
|
|
760
|
+
# # :bool=>{
|
|
761
|
+
# # :must=>{:term=>{:name=>"Moscow"}},
|
|
762
|
+
# # :must_not=>{:bool=>{:must_not=>{:term=>{:name=>"Berlin"}}}}
|
|
763
|
+
# # }
|
|
764
|
+
# # }
|
|
765
|
+
# # }}}}>
|
|
766
766
|
# @param other [Chewy::Search::Request] scope to merge
|
|
767
767
|
# @return [Chewy::Search::Request] new scope
|
|
768
768
|
%i[and or not].each do |name|
|
|
@@ -834,14 +834,14 @@ module Chewy
|
|
|
834
834
|
# @overload first
|
|
835
835
|
# If nothing is passed - it returns a single object.
|
|
836
836
|
#
|
|
837
|
-
# @return [Chewy::
|
|
837
|
+
# @return [Chewy::Index] result document
|
|
838
838
|
#
|
|
839
839
|
# @overload first(limit)
|
|
840
840
|
# If limit is provided - it returns the limit amount or less
|
|
841
841
|
# of wrapper objects.
|
|
842
842
|
#
|
|
843
843
|
# @param limit [Integer] amount of requested results
|
|
844
|
-
# @return [Array<Chewy::
|
|
844
|
+
# @return [Array<Chewy::Index>] result document collection
|
|
845
845
|
def first(limit = UNDEFINED)
|
|
846
846
|
request_limit = limit == UNDEFINED ? 1 : limit
|
|
847
847
|
|
|
@@ -860,7 +860,7 @@ module Chewy
|
|
|
860
860
|
# If single id is passed - it returns a single object.
|
|
861
861
|
#
|
|
862
862
|
# @param id [Integer, String] id of the desired document
|
|
863
|
-
# @return [Chewy::
|
|
863
|
+
# @return [Chewy::Index] result document
|
|
864
864
|
#
|
|
865
865
|
# @overload find(*ids)
|
|
866
866
|
# If several field are passed - it returns an array of wrappers.
|
|
@@ -868,7 +868,7 @@ module Chewy
|
|
|
868
868
|
# batch size - uses scroll API to retrieve everything.
|
|
869
869
|
#
|
|
870
870
|
# @param ids [Array<Integer, String>] ids of the desired documents
|
|
871
|
-
# @return [Array<Chewy::
|
|
871
|
+
# @return [Array<Chewy::Index>] result documents
|
|
872
872
|
def find(*ids)
|
|
873
873
|
return super if block_given?
|
|
874
874
|
|
|
@@ -931,11 +931,10 @@ module Chewy
|
|
|
931
931
|
# @return [Hash] the result of query execution
|
|
932
932
|
def delete_all(refresh: true)
|
|
933
933
|
request_body = only(WHERE_STORAGES).render.merge(refresh: refresh)
|
|
934
|
-
ActiveSupport::Notifications.instrument 'delete_query.chewy',
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
end
|
|
934
|
+
ActiveSupport::Notifications.instrument 'delete_query.chewy', notification_payload(request: request_body) do
|
|
935
|
+
request_body[:body] = {query: {match_all: {}}} if request_body[:body].empty?
|
|
936
|
+
Chewy.client.delete_by_query(request_body)
|
|
937
|
+
end
|
|
939
938
|
end
|
|
940
939
|
|
|
941
940
|
# Returns whether or not the query has been performed.
|
|
@@ -976,14 +975,11 @@ module Chewy
|
|
|
976
975
|
|
|
977
976
|
def perform(additional = {})
|
|
978
977
|
request_body = render.merge(additional)
|
|
979
|
-
ActiveSupport::Notifications.instrument 'search_query.chewy',
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
{}
|
|
985
|
-
end
|
|
986
|
-
end
|
|
978
|
+
ActiveSupport::Notifications.instrument 'search_query.chewy', notification_payload(request: request_body) do
|
|
979
|
+
Chewy.client.search(request_body)
|
|
980
|
+
rescue Elasticsearch::Transport::Transport::Errors::NotFound
|
|
981
|
+
{}
|
|
982
|
+
end
|
|
987
983
|
end
|
|
988
984
|
|
|
989
985
|
def notification_payload(additional)
|