chewy 6.0.0 → 7.6.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/CODEOWNERS +1 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- data/.github/dependabot.yml +42 -0
- data/.github/workflows/ruby.yml +60 -0
- data/.rubocop.yml +16 -8
- data/.rubocop_todo.yml +110 -22
- data/CHANGELOG.md +396 -105
- data/CODE_OF_CONDUCT.md +14 -0
- data/CONTRIBUTING.md +63 -0
- data/Gemfile +4 -10
- data/Guardfile +3 -1
- data/README.md +497 -275
- data/chewy.gemspec +5 -20
- data/gemfiles/base.gemfile +12 -0
- data/gemfiles/rails.6.1.activerecord.gemfile +10 -15
- data/gemfiles/rails.7.0.activerecord.gemfile +14 -0
- data/gemfiles/rails.7.1.activerecord.gemfile +14 -0
- data/lib/chewy/config.rb +60 -52
- data/lib/chewy/elastic_client.rb +31 -0
- data/lib/chewy/errors.rb +7 -10
- data/lib/chewy/fields/base.rb +79 -13
- data/lib/chewy/fields/root.rb +4 -14
- data/lib/chewy/index/actions.rb +54 -37
- data/lib/chewy/{type → index}/adapter/active_record.rb +30 -6
- 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 +17 -18
- data/lib/chewy/index/aliases.rb +14 -5
- data/lib/chewy/index/crutch.rb +40 -0
- data/lib/chewy/index/import/bulk_builder.rb +311 -0
- data/lib/chewy/{type → index}/import/bulk_request.rb +6 -7
- data/lib/chewy/{type → index}/import/journal_builder.rb +11 -12
- data/lib/chewy/{type → index}/import/routine.rb +18 -17
- data/lib/chewy/{type → index}/import.rb +76 -32
- data/lib/chewy/{type → index}/mapping.rb +29 -34
- data/lib/chewy/index/observe/active_record_methods.rb +87 -0
- data/lib/chewy/index/observe/callback.rb +34 -0
- data/lib/chewy/index/observe.rb +17 -0
- data/lib/chewy/index/specification.rb +1 -0
- data/lib/chewy/{type → index}/syncer.rb +59 -59
- data/lib/chewy/{type → index}/witchcraft.rb +11 -7
- data/lib/chewy/{type → index}/wrapper.rb +2 -2
- data/lib/chewy/index.rb +67 -94
- data/lib/chewy/journal.rb +25 -14
- data/lib/chewy/log_subscriber.rb +5 -1
- data/lib/chewy/minitest/helpers.rb +86 -13
- data/lib/chewy/minitest/search_index_receiver.rb +24 -26
- data/lib/chewy/railtie.rb +6 -20
- data/lib/chewy/rake_helper.rb +169 -113
- data/lib/chewy/rspec/build_query.rb +12 -0
- data/lib/chewy/rspec/helpers.rb +55 -0
- data/lib/chewy/rspec/update_index.rb +55 -44
- data/lib/chewy/rspec.rb +2 -0
- data/lib/chewy/runtime/version.rb +1 -1
- data/lib/chewy/runtime.rb +1 -1
- data/lib/chewy/search/loader.rb +19 -41
- data/lib/chewy/search/parameters/collapse.rb +16 -0
- data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
- data/lib/chewy/search/parameters/ignore_unavailable.rb +27 -0
- data/lib/chewy/search/parameters/indices.rb +13 -58
- data/lib/chewy/search/parameters/knn.rb +16 -0
- data/lib/chewy/search/parameters/order.rb +6 -19
- data/lib/chewy/search/parameters/source.rb +5 -1
- data/lib/chewy/search/parameters/storage.rb +1 -1
- data/lib/chewy/search/parameters/track_total_hits.rb +16 -0
- data/lib/chewy/search/parameters.rb +6 -4
- data/lib/chewy/search/query_proxy.rb +9 -2
- data/lib/chewy/search/request.rb +169 -134
- data/lib/chewy/search/response.rb +5 -5
- data/lib/chewy/search/scoping.rb +7 -8
- data/lib/chewy/search/scrolling.rb +13 -13
- data/lib/chewy/search.rb +9 -19
- data/lib/chewy/stash.rb +19 -30
- data/lib/chewy/strategy/active_job.rb +1 -1
- data/lib/chewy/strategy/atomic_no_refresh.rb +18 -0
- data/lib/chewy/strategy/base.rb +10 -0
- data/lib/chewy/strategy/delayed_sidekiq/scheduler.rb +168 -0
- data/lib/chewy/strategy/delayed_sidekiq/worker.rb +76 -0
- data/lib/chewy/strategy/delayed_sidekiq.rb +30 -0
- data/lib/chewy/strategy/lazy_sidekiq.rb +64 -0
- data/lib/chewy/strategy/sidekiq.rb +2 -1
- data/lib/chewy/strategy.rb +6 -19
- data/lib/chewy/version.rb +1 -1
- data/lib/chewy.rb +39 -86
- data/lib/generators/chewy/install_generator.rb +1 -1
- data/lib/tasks/chewy.rake +36 -32
- data/migration_guide.md +46 -8
- data/spec/chewy/config_spec.rb +16 -41
- data/spec/chewy/elastic_client_spec.rb +26 -0
- data/spec/chewy/fields/base_spec.rb +432 -147
- data/spec/chewy/fields/root_spec.rb +20 -28
- data/spec/chewy/fields/time_fields_spec.rb +5 -5
- data/spec/chewy/index/actions_spec.rb +368 -59
- data/spec/chewy/{type → index}/adapter/active_record_spec.rb +156 -40
- data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
- data/spec/chewy/index/aliases_spec.rb +3 -3
- data/spec/chewy/index/import/bulk_builder_spec.rb +494 -0
- data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -12
- data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -19
- data/spec/chewy/{type → index}/import/routine_spec.rb +19 -19
- data/spec/chewy/{type → index}/import_spec.rb +164 -98
- data/spec/chewy/index/mapping_spec.rb +135 -0
- data/spec/chewy/index/observe/active_record_methods_spec.rb +68 -0
- data/spec/chewy/index/observe/callback_spec.rb +139 -0
- data/spec/chewy/index/observe_spec.rb +143 -0
- data/spec/chewy/index/settings_spec.rb +3 -1
- data/spec/chewy/index/specification_spec.rb +20 -30
- 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 +60 -105
- data/spec/chewy/journal_spec.rb +25 -74
- data/spec/chewy/minitest/helpers_spec.rb +123 -15
- data/spec/chewy/minitest/search_index_receiver_spec.rb +28 -30
- data/spec/chewy/multi_search_spec.rb +4 -5
- data/spec/chewy/rake_helper_spec.rb +315 -55
- data/spec/chewy/rspec/build_query_spec.rb +34 -0
- data/spec/chewy/rspec/helpers_spec.rb +61 -0
- data/spec/chewy/rspec/update_index_spec.rb +74 -71
- data/spec/chewy/runtime_spec.rb +2 -2
- data/spec/chewy/search/loader_spec.rb +19 -53
- data/spec/chewy/search/pagination/kaminari_examples.rb +4 -6
- data/spec/chewy/search/pagination/kaminari_spec.rb +2 -2
- data/spec/chewy/search/parameters/collapse_spec.rb +5 -0
- data/spec/chewy/search/parameters/ignore_unavailable_spec.rb +67 -0
- data/spec/chewy/search/parameters/indices_spec.rb +26 -117
- data/spec/chewy/search/parameters/knn_spec.rb +5 -0
- data/spec/chewy/search/parameters/order_spec.rb +18 -11
- 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/track_total_hits_spec.rb +5 -0
- data/spec/chewy/search/parameters_spec.rb +18 -4
- data/spec/chewy/search/query_proxy_spec.rb +68 -17
- data/spec/chewy/search/request_spec.rb +292 -110
- data/spec/chewy/search/response_spec.rb +12 -12
- data/spec/chewy/search/scrolling_spec.rb +10 -17
- data/spec/chewy/search_spec.rb +40 -34
- data/spec/chewy/stash_spec.rb +9 -21
- data/spec/chewy/strategy/active_job_spec.rb +16 -16
- data/spec/chewy/strategy/atomic_no_refresh_spec.rb +60 -0
- data/spec/chewy/strategy/atomic_spec.rb +9 -10
- data/spec/chewy/strategy/delayed_sidekiq_spec.rb +208 -0
- data/spec/chewy/strategy/lazy_sidekiq_spec.rb +214 -0
- data/spec/chewy/strategy/sidekiq_spec.rb +12 -12
- data/spec/chewy/strategy_spec.rb +19 -15
- data/spec/chewy_spec.rb +24 -107
- data/spec/spec_helper.rb +3 -22
- data/spec/support/active_record.rb +25 -7
- metadata +78 -339
- data/.circleci/config.yml +0 -240
- data/Appraisals +0 -81
- data/gemfiles/rails.5.2.activerecord.gemfile +0 -17
- data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
- data/gemfiles/rails.6.0.activerecord.gemfile +0 -17
- data/gemfiles/sequel.4.45.gemfile +0 -11
- data/lib/chewy/backports/deep_dup.rb +0 -46
- data/lib/chewy/backports/duplicable.rb +0 -91
- data/lib/chewy/search/pagination/will_paginate.rb +0 -43
- data/lib/chewy/search/parameters/types.rb +0 -20
- data/lib/chewy/strategy/resque.rb +0 -27
- data/lib/chewy/strategy/shoryuken.rb +0 -40
- 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/chewy/type/crutch.rb +0 -32
- data/lib/chewy/type/import/bulk_builder.rb +0 -122
- data/lib/chewy/type/observe.rb +0 -82
- data/lib/chewy/type.rb +0 -120
- 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/search/parameters/types_spec.rb +0 -5
- 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/import/bulk_builder_spec.rb +0 -194
- data/spec/chewy/type/mapping_spec.rb +0 -175
- 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
data/spec/chewy/journal_spec.rb
CHANGED
@@ -13,14 +13,12 @@ describe Chewy::Journal do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
stub_index("#{namespace}cities") do
|
16
|
-
|
17
|
-
|
18
|
-
end
|
16
|
+
index_scope City
|
17
|
+
default_import_options journal: true
|
19
18
|
end
|
20
19
|
stub_index("#{namespace}countries") do
|
21
|
-
|
22
|
-
|
23
|
-
end
|
20
|
+
index_scope Country
|
21
|
+
default_import_options journal: true
|
24
22
|
end
|
25
23
|
|
26
24
|
Chewy.massacre
|
@@ -67,63 +65,54 @@ describe Chewy::Journal do
|
|
67
65
|
expected_journal = [
|
68
66
|
{
|
69
67
|
'index_name' => "#{namespace}cities",
|
70
|
-
'type_name' => 'city',
|
71
68
|
'action' => 'index',
|
72
69
|
'references' => ['1'].map(&Base64.method(:encode64)),
|
73
70
|
'created_at' => time.utc.as_json
|
74
71
|
},
|
75
72
|
{
|
76
73
|
'index_name' => "#{namespace}cities",
|
77
|
-
'type_name' => 'city',
|
78
74
|
'action' => 'index',
|
79
75
|
'references' => ['2'].map(&Base64.method(:encode64)),
|
80
76
|
'created_at' => time.utc.as_json
|
81
77
|
},
|
82
78
|
{
|
83
79
|
'index_name' => "#{namespace}countries",
|
84
|
-
'type_name' => 'country',
|
85
80
|
'action' => 'index',
|
86
81
|
'references' => ['1'].map(&Base64.method(:encode64)),
|
87
82
|
'created_at' => time.utc.as_json
|
88
83
|
},
|
89
84
|
{
|
90
85
|
'index_name' => "#{namespace}countries",
|
91
|
-
'type_name' => 'country',
|
92
86
|
'action' => 'index',
|
93
87
|
'references' => ['2'].map(&Base64.method(:encode64)),
|
94
88
|
'created_at' => time.utc.as_json
|
95
89
|
},
|
96
90
|
{
|
97
91
|
'index_name' => "#{namespace}countries",
|
98
|
-
'type_name' => 'country',
|
99
92
|
'action' => 'index',
|
100
93
|
'references' => ['3'].map(&Base64.method(:encode64)),
|
101
94
|
'created_at' => time.utc.as_json
|
102
95
|
},
|
103
96
|
{
|
104
97
|
'index_name' => "#{namespace}cities",
|
105
|
-
'type_name' => 'city',
|
106
98
|
'action' => 'index',
|
107
99
|
'references' => %w[1 2].map(&Base64.method(:encode64)),
|
108
100
|
'created_at' => import_time.utc.as_json
|
109
101
|
},
|
110
102
|
{
|
111
103
|
'index_name' => "#{namespace}countries",
|
112
|
-
'type_name' => 'country',
|
113
104
|
'action' => 'index',
|
114
105
|
'references' => %w[1 2 3].map(&Base64.method(:encode64)),
|
115
106
|
'created_at' => import_time.utc.as_json
|
116
107
|
},
|
117
108
|
{
|
118
109
|
'index_name' => "#{namespace}cities",
|
119
|
-
'type_name' => 'city',
|
120
110
|
'action' => 'index',
|
121
111
|
'references' => ['1'].map(&Base64.method(:encode64)),
|
122
112
|
'created_at' => update_time.utc.as_json
|
123
113
|
},
|
124
114
|
{
|
125
115
|
'index_name' => "#{namespace}countries",
|
126
|
-
'type_name' => 'country',
|
127
116
|
'action' => 'delete',
|
128
117
|
'references' => ['2'].map(&Base64.method(:encode64)),
|
129
118
|
'created_at' => destroy_time.utc.as_json
|
@@ -137,7 +126,7 @@ describe Chewy::Journal do
|
|
137
126
|
expect(journal_entries.size).to eq 4
|
138
127
|
|
139
128
|
# simulate lost data
|
140
|
-
Chewy.client.delete(index: "#{Chewy.settings[:prefix]}_cities",
|
129
|
+
Chewy.client.delete(index: "#{Chewy.settings[:prefix]}_cities", id: 1, refresh: true)
|
141
130
|
expect(cities_index.count).to eq 1
|
142
131
|
|
143
132
|
described_class.new.apply(time)
|
@@ -166,14 +155,12 @@ describe Chewy::Journal do
|
|
166
155
|
end
|
167
156
|
|
168
157
|
stub_index(:cities) do
|
169
|
-
|
170
|
-
|
171
|
-
end
|
158
|
+
index_scope City
|
159
|
+
default_import_options journal: true
|
172
160
|
end
|
173
161
|
stub_index(:countries) do
|
174
|
-
|
175
|
-
|
176
|
-
end
|
162
|
+
index_scope Country
|
163
|
+
default_import_options journal: true
|
177
164
|
end
|
178
165
|
end
|
179
166
|
|
@@ -192,8 +179,8 @@ describe Chewy::Journal do
|
|
192
179
|
Array.new(2) { |i| Country.create!(id: i + 1) }
|
193
180
|
|
194
181
|
# simulate lost data
|
195
|
-
Chewy.client.delete(index: 'cities',
|
196
|
-
Chewy.client.delete(index: 'countries',
|
182
|
+
Chewy.client.delete(index: 'cities', id: 1, refresh: true)
|
183
|
+
Chewy.client.delete(index: 'countries', id: 1, refresh: true)
|
197
184
|
expect(CitiesIndex.all.to_a.length).to eq 1
|
198
185
|
expect(CountriesIndex.all.to_a.length).to eq 1
|
199
186
|
|
@@ -203,7 +190,7 @@ describe Chewy::Journal do
|
|
203
190
|
expect(CountriesIndex.all.to_a.length).to eq 1
|
204
191
|
|
205
192
|
# Replay on both
|
206
|
-
Chewy.client.delete(index: 'cities',
|
193
|
+
Chewy.client.delete(index: 'cities', id: 1, refresh: true)
|
207
194
|
expect(CitiesIndex.all.to_a.length).to eq 1
|
208
195
|
expect(described_class.new(CitiesIndex, CountriesIndex).apply(time)).to eq(4)
|
209
196
|
expect(CitiesIndex.all.to_a.length).to eq 2
|
@@ -212,59 +199,23 @@ describe Chewy::Journal do
|
|
212
199
|
end
|
213
200
|
end
|
214
201
|
|
215
|
-
context '
|
216
|
-
let(:time) { Time.now
|
217
|
-
before do
|
218
|
-
Timecop.freeze
|
219
|
-
Chewy.strategy(:urgent)
|
220
|
-
City.create!(id: 1)
|
221
|
-
end
|
222
|
-
|
223
|
-
after do
|
224
|
-
Chewy.strategy.pop
|
225
|
-
Timecop.return
|
226
|
-
end
|
227
|
-
|
228
|
-
specify 'journal was cleaned after the first call' do
|
229
|
-
expect(Chewy::Stash::Journal).to receive(:entries).exactly(2).and_call_original
|
230
|
-
expect(described_class.new.apply(time)).to eq(1)
|
231
|
-
end
|
232
|
-
|
233
|
-
context 'endless journal' do
|
234
|
-
let(:count_of_checks) { 10 } # default
|
235
|
-
let!(:journal_entries) do
|
236
|
-
record = Chewy::Stash::Journal.entries(time).first
|
237
|
-
Array.new(count_of_checks) do |i|
|
238
|
-
Chewy::Stash::Journal::Journal.new(
|
239
|
-
record.attributes.merge(
|
240
|
-
'created_at' => time.to_i + i,
|
241
|
-
'references' => [i.to_s]
|
242
|
-
)
|
243
|
-
)
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
specify '10 retries by default' do
|
248
|
-
expect(Chewy::Stash::Journal)
|
249
|
-
.to receive(:entries).exactly(count_of_checks) { [journal_entries.shift].compact }
|
250
|
-
expect(described_class.new.apply(time)).to eq(10)
|
251
|
-
end
|
202
|
+
context 'when order is not preserved' do
|
203
|
+
let(:time) { Time.now }
|
252
204
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
205
|
+
it 'paginates properly through all items' do
|
206
|
+
Chewy.strategy(:urgent) do
|
207
|
+
Timecop.travel(time + 1.minute) { City.create!(id: 2) }
|
208
|
+
Timecop.travel(time + 3.minute) { City.create!(id: 4) }
|
209
|
+
Timecop.travel(time + 2.minute) { City.create!(id: 1) }
|
210
|
+
Timecop.travel(time + 4.minute) { City.create!(id: 3) }
|
257
211
|
end
|
258
212
|
|
259
|
-
|
260
|
-
|
213
|
+
CitiesIndex.purge!
|
214
|
+
expect(CitiesIndex.all.to_a.length).to eq 0
|
261
215
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
expect(described_class.new.apply(time, retries: retries)).to eq(5)
|
266
|
-
end
|
267
|
-
end
|
216
|
+
# Replay on specific index
|
217
|
+
expect(described_class.new(CitiesIndex).apply(time, fetch_limit: 2)).to eq(4)
|
218
|
+
expect(CitiesIndex.all.to_a.map(&:id).sort).to eq([1, 2, 3, 4])
|
268
219
|
end
|
269
220
|
end
|
270
221
|
end
|
@@ -10,7 +10,11 @@ describe :minitest_helper do
|
|
10
10
|
expect(haystack).to include(needle)
|
11
11
|
end
|
12
12
|
|
13
|
-
include
|
13
|
+
include Chewy::Minitest::Helpers
|
14
|
+
|
15
|
+
def assert_equal(expected, actual, message)
|
16
|
+
raise message unless expected == actual
|
17
|
+
end
|
14
18
|
|
15
19
|
before do
|
16
20
|
Chewy.massacre
|
@@ -18,8 +22,112 @@ describe :minitest_helper do
|
|
18
22
|
|
19
23
|
before do
|
20
24
|
stub_index(:dummies) do
|
21
|
-
|
22
|
-
|
25
|
+
root value: ->(_o) { {} }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'mock_elasticsearch_response' do
|
30
|
+
let(:hits) do
|
31
|
+
[
|
32
|
+
{
|
33
|
+
'_index' => 'dummies',
|
34
|
+
'_type' => '_doc',
|
35
|
+
'_id' => '2',
|
36
|
+
'_score' => 3.14,
|
37
|
+
'_source' => source
|
38
|
+
}
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:source) { {'name' => 'some_name', id: '2'} }
|
43
|
+
let(:sources) { [source] }
|
44
|
+
|
45
|
+
context 'mocks by raw response' do
|
46
|
+
let(:raw_response) do
|
47
|
+
{
|
48
|
+
'took' => 4,
|
49
|
+
'timed_out' => false,
|
50
|
+
'_shards' => {
|
51
|
+
'total' => 1,
|
52
|
+
'successful' => 1,
|
53
|
+
'skipped' => 0,
|
54
|
+
'failed' => 0
|
55
|
+
},
|
56
|
+
'hits' => {
|
57
|
+
'total' => {
|
58
|
+
'value' => 1,
|
59
|
+
'relation' => 'eq'
|
60
|
+
},
|
61
|
+
'max_score' => 1.0,
|
62
|
+
'hits' => hits
|
63
|
+
}
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
specify do
|
68
|
+
mock_elasticsearch_response(DummiesIndex, raw_response) do
|
69
|
+
expect(DummiesIndex.query({}).hits).to eq(hits)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'mocks by response sources' do
|
75
|
+
specify do
|
76
|
+
mock_elasticsearch_response_sources(DummiesIndex, sources) do
|
77
|
+
expect(DummiesIndex.query({}).hits).to eq(hits)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'assert correct elasticsearch query' do
|
84
|
+
let(:query) do
|
85
|
+
DummiesIndex.filter.should { multi_match foo: 'bar' }.filter { match foo: 'bar' }
|
86
|
+
end
|
87
|
+
|
88
|
+
let(:expected_query) do
|
89
|
+
{
|
90
|
+
index: ['dummies'],
|
91
|
+
body: {
|
92
|
+
query: {
|
93
|
+
bool: {
|
94
|
+
filter: {
|
95
|
+
bool: {
|
96
|
+
must: {
|
97
|
+
match: {foo: 'bar'}
|
98
|
+
},
|
99
|
+
should: {
|
100
|
+
multi_match: {foo: 'bar'}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'will be built' do
|
111
|
+
specify do
|
112
|
+
expect { assert_elasticsearch_query(query, expected_query) }.not_to raise_error
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'will not be built' do
|
117
|
+
let(:unexpected_query) do
|
118
|
+
{
|
119
|
+
index: ['what?'],
|
120
|
+
body: {}
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
let(:unexpected_query_error_message) do
|
125
|
+
'got {:index=>["dummies"], :body=>{:query=>{:bool=>{:filter=>{:bool=>{:must=>{:match=>{:foo=>"bar"}}, :should=>{:multi_match=>{:foo=>"bar"}}}}}}}} instead of expected query.'
|
126
|
+
end
|
127
|
+
|
128
|
+
specify do
|
129
|
+
expect { assert_elasticsearch_query(query, unexpected_query) }
|
130
|
+
.to raise_error(RuntimeError, unexpected_query_error_message)
|
23
131
|
end
|
24
132
|
end
|
25
133
|
end
|
@@ -27,45 +135,45 @@ describe :minitest_helper do
|
|
27
135
|
context 'assert_indexes' do
|
28
136
|
specify 'doesn\'t fail when index updates correctly' do
|
29
137
|
expect do
|
30
|
-
assert_indexes DummiesIndex
|
31
|
-
DummiesIndex
|
138
|
+
assert_indexes DummiesIndex do
|
139
|
+
DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
|
32
140
|
end
|
33
141
|
end.to_not raise_error
|
34
142
|
end
|
35
143
|
|
36
144
|
specify 'fails when index doesn\'t update' do
|
37
145
|
expect do
|
38
|
-
assert_indexes DummiesIndex
|
146
|
+
assert_indexes DummiesIndex do
|
39
147
|
end
|
40
148
|
end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
41
149
|
end
|
42
150
|
|
43
151
|
specify 'SearchIndexReceiver catches the indexes' do
|
44
|
-
receiver = assert_indexes DummiesIndex
|
45
|
-
DummiesIndex
|
152
|
+
receiver = assert_indexes DummiesIndex do
|
153
|
+
DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
|
46
154
|
end
|
47
155
|
|
48
156
|
expect(receiver).to be_a(SearchIndexReceiver)
|
49
157
|
|
50
158
|
expect(
|
51
|
-
receiver.indexes_for(DummiesIndex
|
159
|
+
receiver.indexes_for(DummiesIndex)
|
52
160
|
.map { |index| index[:_id] }
|
53
161
|
).to match_array([41, 42])
|
54
162
|
end
|
55
163
|
|
56
164
|
specify 'Real index is bypassed when asserting' do
|
57
|
-
expect(DummiesIndex
|
165
|
+
expect(DummiesIndex).not_to receive(:bulk)
|
58
166
|
|
59
|
-
assert_indexes DummiesIndex
|
60
|
-
DummiesIndex
|
167
|
+
assert_indexes DummiesIndex do
|
168
|
+
DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
|
61
169
|
end
|
62
170
|
end
|
63
171
|
|
64
172
|
specify 'Real index is allowed when asserting' do
|
65
|
-
expect(DummiesIndex
|
173
|
+
expect(DummiesIndex).to receive(:bulk)
|
66
174
|
|
67
|
-
assert_indexes DummiesIndex
|
68
|
-
DummiesIndex
|
175
|
+
assert_indexes DummiesIndex, bypass_actual_index: false do
|
176
|
+
DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
|
69
177
|
end
|
70
178
|
end
|
71
179
|
end
|
@@ -24,99 +24,97 @@ describe :search_index_receiver do
|
|
24
24
|
SearchIndexReceiver.new
|
25
25
|
end
|
26
26
|
|
27
|
+
let(:dummy_class) { Struct.new(:id) }
|
28
|
+
|
27
29
|
before do
|
28
30
|
stub_index(:dummies) do
|
29
|
-
|
30
|
-
root value: ->(_o) { {} }
|
31
|
-
end
|
31
|
+
root value: ->(_o) { {} }
|
32
32
|
end
|
33
33
|
|
34
34
|
stub_index(:dummies2) do
|
35
|
-
|
36
|
-
root value: ->(_o) { {} }
|
37
|
-
end
|
35
|
+
root value: ->(_o) { {} }
|
38
36
|
end
|
39
37
|
end
|
40
38
|
|
41
39
|
context 'catch' do
|
42
40
|
specify 'archives more than one type' do
|
43
|
-
receiver.catch search_request(2), DummiesIndex
|
44
|
-
receiver.catch search_request(3), Dummies2Index
|
45
|
-
expect(receiver.indexes.keys).to match_array([DummiesIndex
|
41
|
+
receiver.catch search_request(2), DummiesIndex
|
42
|
+
receiver.catch search_request(3), Dummies2Index
|
43
|
+
expect(receiver.indexes.keys).to match_array([DummiesIndex, Dummies2Index])
|
46
44
|
end
|
47
45
|
end
|
48
46
|
|
49
47
|
context 'indexes_for' do
|
50
48
|
before do
|
51
|
-
receiver.catch search_request(2), DummiesIndex
|
52
|
-
receiver.catch search_request(3), Dummies2Index
|
49
|
+
receiver.catch search_request(2), DummiesIndex
|
50
|
+
receiver.catch search_request(3), Dummies2Index
|
53
51
|
end
|
54
52
|
|
55
53
|
specify 'returns indexes for a specific type' do
|
56
|
-
expect(parse_request(receiver.indexes_for(DummiesIndex
|
54
|
+
expect(parse_request(receiver.indexes_for(DummiesIndex))).to match_array([1, 2])
|
57
55
|
end
|
58
56
|
|
59
57
|
specify 'returns only indexes for all types' do
|
60
58
|
index_responses = receiver.indexes
|
61
|
-
expect(index_responses.keys).to match_array([DummiesIndex
|
59
|
+
expect(index_responses.keys).to match_array([DummiesIndex, Dummies2Index])
|
62
60
|
expect(parse_request(index_responses.values.flatten)).to match_array([1, 2, 1, 2, 3])
|
63
61
|
end
|
64
62
|
end
|
65
63
|
|
66
64
|
context 'deletes_for' do
|
67
65
|
before do
|
68
|
-
receiver.catch search_request(2, verb: :delete), DummiesIndex
|
69
|
-
receiver.catch search_request(3, verb: :delete), Dummies2Index
|
66
|
+
receiver.catch search_request(2, verb: :delete), DummiesIndex
|
67
|
+
receiver.catch search_request(3, verb: :delete), Dummies2Index
|
70
68
|
end
|
71
69
|
|
72
70
|
specify 'returns deletes for a specific type' do
|
73
|
-
expect(receiver.deletes_for(Dummies2Index
|
71
|
+
expect(receiver.deletes_for(Dummies2Index)).to match_array([1, 2, 3])
|
74
72
|
end
|
75
73
|
|
76
74
|
specify 'returns only deletes for all types' do
|
77
75
|
deletes = receiver.deletes
|
78
|
-
expect(deletes.keys).to match_array([DummiesIndex
|
76
|
+
expect(deletes.keys).to match_array([DummiesIndex, Dummies2Index])
|
79
77
|
expect(deletes.values.flatten).to match_array([1, 2, 1, 2, 3])
|
80
78
|
end
|
81
79
|
end
|
82
80
|
|
83
81
|
context 'indexed?' do
|
84
82
|
before do
|
85
|
-
receiver.catch search_request(1), DummiesIndex
|
83
|
+
receiver.catch search_request(1), DummiesIndex
|
86
84
|
end
|
87
85
|
|
88
86
|
specify 'validates that an object was indexed' do
|
89
|
-
dummy =
|
90
|
-
expect(receiver.indexed?(dummy, DummiesIndex
|
87
|
+
dummy = dummy_class.new(1)
|
88
|
+
expect(receiver.indexed?(dummy, DummiesIndex)).to be(true)
|
91
89
|
end
|
92
90
|
|
93
91
|
specify 'doesn\'t validate than unindexed objects were indexed' do
|
94
|
-
dummy =
|
95
|
-
expect(receiver.indexed?(dummy, DummiesIndex
|
92
|
+
dummy = dummy_class.new(2)
|
93
|
+
expect(receiver.indexed?(dummy, DummiesIndex)).to be(false)
|
96
94
|
end
|
97
95
|
end
|
98
96
|
|
99
97
|
context 'deleted?' do
|
100
98
|
before do
|
101
|
-
receiver.catch search_request(1, verb: :delete), DummiesIndex
|
99
|
+
receiver.catch search_request(1, verb: :delete), DummiesIndex
|
102
100
|
end
|
103
101
|
|
104
102
|
specify 'validates than an object was deleted' do
|
105
|
-
dummy =
|
106
|
-
expect(receiver.deleted?(dummy, DummiesIndex
|
103
|
+
dummy = dummy_class.new(1)
|
104
|
+
expect(receiver.deleted?(dummy, DummiesIndex)).to be(true)
|
107
105
|
end
|
108
106
|
|
109
107
|
specify 'doesn\'t validate than undeleted objects were deleted' do
|
110
|
-
dummy =
|
111
|
-
expect(receiver.deleted?(dummy, DummiesIndex
|
108
|
+
dummy = dummy_class.new(2)
|
109
|
+
expect(receiver.deleted?(dummy, DummiesIndex)).to be(false)
|
112
110
|
end
|
113
111
|
end
|
114
112
|
|
115
113
|
context 'updated_indexes' do
|
116
114
|
specify 'provides a list of indices updated' do
|
117
|
-
receiver.catch search_request(2, verb: :delete), DummiesIndex
|
118
|
-
receiver.catch search_request(3, verb: :delete), Dummies2Index
|
119
|
-
expect(receiver.updated_indexes).to match_array([DummiesIndex
|
115
|
+
receiver.catch search_request(2, verb: :delete), DummiesIndex
|
116
|
+
receiver.catch search_request(3, verb: :delete), Dummies2Index
|
117
|
+
expect(receiver.updated_indexes).to match_array([DummiesIndex, Dummies2Index])
|
120
118
|
end
|
121
119
|
end
|
122
120
|
end
|
@@ -13,10 +13,9 @@ describe Chewy::MultiSearch do
|
|
13
13
|
aggs(country: {terms: {field: :country_id}})
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
16
|
+
index_scope City
|
17
|
+
field :name, type: 'keyword'
|
18
|
+
field :country_id, type: 'keyword'
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
@@ -78,7 +77,7 @@ describe Chewy::MultiSearch do
|
|
78
77
|
is_expected.to have(2).responses
|
79
78
|
expect(responses[0]).to be_a(Chewy::Search::Response)
|
80
79
|
expect(responses[1]).to be_a(Chewy::Search::Response)
|
81
|
-
expect(responses[1].wrappers).to all(be_a CitiesIndex
|
80
|
+
expect(responses[1].wrappers).to all(be_a CitiesIndex)
|
82
81
|
end
|
83
82
|
end
|
84
83
|
end
|