chewy 0.10.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +240 -0
- data/.rubocop.yml +25 -25
- data/Appraisals +12 -10
- data/CHANGELOG.md +252 -263
- data/Gemfile +5 -1
- data/LICENSE.txt +1 -1
- data/README.md +142 -78
- data/chewy.gemspec +10 -12
- data/gemfiles/{rails.4.2.mongoid.5.1.gemfile → rails.5.2.activerecord.gemfile} +6 -4
- data/gemfiles/{rails.4.2.activerecord.gemfile → rails.5.2.mongoid.6.4.gemfile} +6 -4
- data/gemfiles/{rails.4.0.activerecord.gemfile → rails.6.0.activerecord.gemfile} +6 -3
- data/gemfiles/rails.6.1.activerecord.gemfile +19 -0
- data/gemfiles/sequel.4.45.gemfile +2 -2
- data/lib/chewy.rb +2 -1
- data/lib/chewy/backports/duplicable.rb +1 -1
- data/lib/chewy/config.rb +10 -39
- data/lib/chewy/fields/base.rb +40 -28
- data/lib/chewy/fields/root.rb +18 -11
- data/lib/chewy/index.rb +3 -1
- data/lib/chewy/index/actions.rb +27 -15
- data/lib/chewy/index/settings.rb +2 -0
- data/lib/chewy/index/specification.rb +12 -10
- data/lib/chewy/minitest/helpers.rb +6 -6
- data/lib/chewy/minitest/search_index_receiver.rb +17 -17
- data/lib/chewy/multi_search.rb +62 -0
- data/lib/chewy/railtie.rb +4 -4
- data/lib/chewy/rake_helper.rb +5 -5
- data/lib/chewy/rspec/update_index.rb +3 -5
- data/lib/chewy/search.rb +4 -11
- data/lib/chewy/search/loader.rb +1 -1
- data/lib/chewy/search/pagination/will_paginate.rb +4 -2
- data/lib/chewy/search/parameters.rb +24 -6
- data/lib/chewy/search/parameters/allow_partial_search_results.rb +27 -0
- data/lib/chewy/search/parameters/concerns/query_storage.rb +4 -3
- data/lib/chewy/search/parameters/indices.rb +123 -0
- data/lib/chewy/search/parameters/none.rb +1 -3
- data/lib/chewy/search/request.rb +100 -74
- data/lib/chewy/search/scrolling.rb +7 -6
- data/lib/chewy/stash.rb +30 -21
- data/lib/chewy/strategy/active_job.rb +1 -1
- data/lib/chewy/strategy/atomic.rb +1 -1
- data/lib/chewy/strategy/sidekiq.rb +1 -1
- data/lib/chewy/type.rb +5 -2
- data/lib/chewy/type/adapter/active_record.rb +1 -1
- data/lib/chewy/type/adapter/base.rb +9 -9
- data/lib/chewy/type/adapter/mongoid.rb +2 -4
- data/lib/chewy/type/adapter/orm.rb +7 -4
- data/lib/chewy/type/adapter/sequel.rb +5 -7
- data/lib/chewy/type/crutch.rb +1 -1
- data/lib/chewy/type/import.rb +13 -11
- data/lib/chewy/type/import/bulk_builder.rb +1 -1
- data/lib/chewy/type/import/bulk_request.rb +4 -2
- data/lib/chewy/type/import/journal_builder.rb +3 -3
- data/lib/chewy/type/import/routine.rb +3 -3
- data/lib/chewy/type/mapping.rb +42 -36
- data/lib/chewy/type/observe.rb +16 -12
- data/lib/chewy/type/syncer.rb +15 -14
- data/lib/chewy/type/witchcraft.rb +11 -7
- data/lib/chewy/type/wrapper.rb +14 -4
- data/lib/chewy/version.rb +1 -1
- data/lib/sequel/plugins/chewy_observe.rb +4 -19
- data/migration_guide.md +18 -0
- data/spec/chewy/config_spec.rb +16 -21
- data/spec/chewy/fields/base_spec.rb +70 -70
- data/spec/chewy/fields/root_spec.rb +56 -9
- data/spec/chewy/index/actions_spec.rb +63 -7
- data/spec/chewy/index/specification_spec.rb +25 -16
- data/spec/chewy/index_spec.rb +75 -45
- data/spec/chewy/journal_spec.rb +33 -29
- data/spec/chewy/minitest/search_index_receiver_spec.rb +11 -9
- data/spec/chewy/multi_search_spec.rb +85 -0
- data/spec/chewy/rake_helper_spec.rb +123 -95
- data/spec/chewy/rspec/update_index_spec.rb +47 -46
- data/spec/chewy/runtime_spec.rb +2 -2
- data/spec/chewy/search/pagination/kaminari_spec.rb +7 -3
- data/spec/chewy/search/pagination/will_paginate_spec.rb +9 -3
- data/spec/chewy/search/parameters/indices_spec.rb +190 -0
- data/spec/chewy/search/parameters/none_spec.rb +1 -1
- data/spec/chewy/search/parameters_spec.rb +21 -4
- data/spec/chewy/search/request_spec.rb +101 -70
- data/spec/chewy/search/response_spec.rb +27 -17
- data/spec/chewy/search/scrolling_spec.rb +25 -16
- data/spec/chewy/search_spec.rb +49 -35
- data/spec/chewy/stash_spec.rb +15 -13
- data/spec/chewy/strategy/active_job_spec.rb +15 -2
- data/spec/chewy/strategy/shoryuken_spec.rb +8 -2
- data/spec/chewy/strategy/sidekiq_spec.rb +6 -2
- data/spec/chewy/type/adapter/active_record_spec.rb +16 -4
- data/spec/chewy/type/import/bulk_builder_spec.rb +9 -94
- data/spec/chewy/type/import/journal_builder_spec.rb +17 -15
- data/spec/chewy/type/import_spec.rb +6 -0
- data/spec/chewy/type/mapping_spec.rb +51 -18
- data/spec/chewy/type/observe_spec.rb +4 -4
- data/spec/chewy/type/witchcraft_spec.rb +31 -0
- data/spec/chewy/type/wrapper_spec.rb +3 -1
- data/spec/chewy_spec.rb +0 -7
- data/spec/spec_helper.rb +5 -1
- data/spec/support/active_record.rb +20 -0
- metadata +46 -116
- data/.travis.yml +0 -53
- data/LEGACY_DSL.md +0 -497
- data/gemfiles/rails.4.1.activerecord.gemfile +0 -14
- data/gemfiles/rails.5.0.activerecord.gemfile +0 -15
- data/gemfiles/rails.5.0.mongoid.6.0.gemfile +0 -15
- data/gemfiles/rails.5.1.activerecord.gemfile +0 -15
- data/gemfiles/rails.5.1.mongoid.6.1.gemfile +0 -15
- data/lib/chewy/query.rb +0 -1098
- data/lib/chewy/query/compose.rb +0 -68
- data/lib/chewy/query/criteria.rb +0 -191
- data/lib/chewy/query/filters.rb +0 -227
- data/lib/chewy/query/loading.rb +0 -111
- data/lib/chewy/query/nodes/and.rb +0 -25
- data/lib/chewy/query/nodes/base.rb +0 -17
- data/lib/chewy/query/nodes/bool.rb +0 -34
- data/lib/chewy/query/nodes/equal.rb +0 -34
- data/lib/chewy/query/nodes/exists.rb +0 -20
- data/lib/chewy/query/nodes/expr.rb +0 -28
- data/lib/chewy/query/nodes/field.rb +0 -110
- data/lib/chewy/query/nodes/has_child.rb +0 -15
- data/lib/chewy/query/nodes/has_parent.rb +0 -15
- data/lib/chewy/query/nodes/has_relation.rb +0 -59
- data/lib/chewy/query/nodes/match_all.rb +0 -11
- data/lib/chewy/query/nodes/missing.rb +0 -20
- data/lib/chewy/query/nodes/not.rb +0 -25
- data/lib/chewy/query/nodes/or.rb +0 -25
- data/lib/chewy/query/nodes/prefix.rb +0 -19
- data/lib/chewy/query/nodes/query.rb +0 -20
- data/lib/chewy/query/nodes/range.rb +0 -63
- data/lib/chewy/query/nodes/raw.rb +0 -15
- data/lib/chewy/query/nodes/regexp.rb +0 -35
- data/lib/chewy/query/nodes/script.rb +0 -20
- data/lib/chewy/query/pagination.rb +0 -25
- data/spec/chewy/query/criteria_spec.rb +0 -700
- data/spec/chewy/query/filters_spec.rb +0 -201
- data/spec/chewy/query/loading_spec.rb +0 -124
- data/spec/chewy/query/nodes/and_spec.rb +0 -12
- data/spec/chewy/query/nodes/bool_spec.rb +0 -14
- data/spec/chewy/query/nodes/equal_spec.rb +0 -32
- data/spec/chewy/query/nodes/exists_spec.rb +0 -18
- data/spec/chewy/query/nodes/has_child_spec.rb +0 -59
- data/spec/chewy/query/nodes/has_parent_spec.rb +0 -59
- data/spec/chewy/query/nodes/match_all_spec.rb +0 -11
- data/spec/chewy/query/nodes/missing_spec.rb +0 -16
- data/spec/chewy/query/nodes/not_spec.rb +0 -13
- data/spec/chewy/query/nodes/or_spec.rb +0 -12
- data/spec/chewy/query/nodes/prefix_spec.rb +0 -16
- data/spec/chewy/query/nodes/query_spec.rb +0 -12
- data/spec/chewy/query/nodes/range_spec.rb +0 -32
- data/spec/chewy/query/nodes/raw_spec.rb +0 -11
- data/spec/chewy/query/nodes/regexp_spec.rb +0 -43
- data/spec/chewy/query/nodes/script_spec.rb +0 -15
- data/spec/chewy/query/pagination/kaminari_spec.rb +0 -5
- data/spec/chewy/query/pagination/will_paginate_spec.rb +0 -5
- data/spec/chewy/query/pagination_spec.rb +0 -39
- data/spec/chewy/query_spec.rb +0 -636
- data/spec/chewy/search/parameters/indices_boost_spec.rb +0 -83
@@ -72,18 +72,20 @@ describe Chewy::Search::Parameters do
|
|
72
72
|
describe '#merge!' do
|
73
73
|
let(:first) { described_class.new(offset: 10, order: 'foo') }
|
74
74
|
let(:second) { described_class.new(limit: 20, offset: 20, order: 'bar') }
|
75
|
+
let(:first_clone) { first.clone }
|
76
|
+
let(:second_clone) { second.clone }
|
75
77
|
|
76
78
|
specify do
|
77
79
|
expect { first.merge!(second) }.to change { first.clone }
|
78
80
|
.to(described_class.new(limit: 20, offset: 20, order: %w[foo bar]))
|
79
81
|
end
|
80
|
-
specify { expect { first.merge!(second) }.not_to change {
|
82
|
+
specify { expect { first.merge!(second) }.not_to change { second_clone } }
|
81
83
|
|
82
84
|
specify do
|
83
85
|
expect { second.merge!(first) }.to change { second.clone }
|
84
86
|
.to(described_class.new(limit: 20, offset: 10, order: %w[bar foo]))
|
85
87
|
end
|
86
|
-
specify { expect { second.merge!(first) }.not_to change {
|
88
|
+
specify { expect { second.merge!(first) }.not_to change { first_clone } }
|
87
89
|
|
88
90
|
context 'spawns new storages for the merge' do
|
89
91
|
let(:names) { %i[limit offset order] }
|
@@ -100,7 +102,22 @@ describe Chewy::Search::Parameters do
|
|
100
102
|
subject { described_class.new(offset: 10, order: 'foo') }
|
101
103
|
|
102
104
|
specify { expect(subject.render).to eq(body: {from: 10, sort: ['foo']}) }
|
103
|
-
specify { expect(described_class.new.render).to eq({}) }
|
105
|
+
specify { expect(described_class.new.render).to eq(body: {}) }
|
106
|
+
|
107
|
+
context do
|
108
|
+
subject { described_class.new(request_cache: true) }
|
109
|
+
specify { expect(subject.render).to eq(body: {}, request_cache: true) }
|
110
|
+
end
|
111
|
+
|
112
|
+
context do
|
113
|
+
subject { described_class.new(search_type: 'query_then_fetch') }
|
114
|
+
specify { expect(subject.render).to eq(body: {}, search_type: 'query_then_fetch') }
|
115
|
+
end
|
116
|
+
|
117
|
+
context do
|
118
|
+
subject { described_class.new(allow_partial_search_results: true) }
|
119
|
+
specify { expect(subject.render).to eq(body: {}, allow_partial_search_results: true) }
|
120
|
+
end
|
104
121
|
|
105
122
|
context do
|
106
123
|
subject { described_class.new(query: {foo: 'bar'}, filter: {moo: 'baz'}) }
|
@@ -124,7 +141,7 @@ describe Chewy::Search::Parameters do
|
|
124
141
|
|
125
142
|
context do
|
126
143
|
subject { described_class.new(filter: {moo: 'baz'}, none: true) }
|
127
|
-
specify { expect(subject.render).to eq(body: {query: {
|
144
|
+
specify { expect(subject.render).to eq(body: {query: {match_none: {}}}) }
|
128
145
|
end
|
129
146
|
end
|
130
147
|
end
|
@@ -10,17 +10,19 @@ describe Chewy::Search::Request do
|
|
10
10
|
field :name
|
11
11
|
field :age, type: :integer
|
12
12
|
end
|
13
|
+
end
|
14
|
+
|
15
|
+
stub_index(:cities) do
|
13
16
|
define_type :city do
|
14
17
|
field :id, type: :integer
|
15
18
|
end
|
19
|
+
end
|
20
|
+
|
21
|
+
stub_index(:countries) do
|
16
22
|
define_type :country do
|
17
23
|
field :id, type: :integer
|
18
24
|
end
|
19
25
|
end
|
20
|
-
|
21
|
-
stub_index(:cities) do
|
22
|
-
define_type :city
|
23
|
-
end
|
24
26
|
end
|
25
27
|
|
26
28
|
subject { described_class.new(ProductsIndex) }
|
@@ -30,11 +32,7 @@ describe Chewy::Search::Request do
|
|
30
32
|
specify { expect(described_class.new(ProductsIndex)).not_to eq(described_class.new(CitiesIndex)) }
|
31
33
|
specify { expect(described_class.new(ProductsIndex)).not_to eq(described_class.new(ProductsIndex, CitiesIndex)) }
|
32
34
|
specify { expect(described_class.new(CitiesIndex, ProductsIndex)).to eq(described_class.new(ProductsIndex, CitiesIndex)) }
|
33
|
-
specify { expect(described_class.new(ProductsIndex
|
34
|
-
specify { expect(described_class.new(ProductsIndex::Product)).not_to eq(described_class.new(ProductsIndex::City)) }
|
35
|
-
specify { expect(described_class.new(ProductsIndex::Product)).not_to eq(described_class.new(ProductsIndex::Product, ProductsIndex::City)) }
|
36
|
-
specify { expect(described_class.new(ProductsIndex::City, ProductsIndex::Product)).to eq(described_class.new(ProductsIndex::Product, ProductsIndex::City)) }
|
37
|
-
specify { expect(described_class.new(ProductsIndex::City, CitiesIndex::City)).to eq(described_class.new(CitiesIndex::City, ProductsIndex::City)) }
|
35
|
+
specify { expect(described_class.new(ProductsIndex, CitiesIndex)).to eq(described_class.new(CitiesIndex, ProductsIndex)) }
|
38
36
|
|
39
37
|
specify { expect(described_class.new(ProductsIndex).limit(10)).to eq(described_class.new(ProductsIndex).limit(10)) }
|
40
38
|
specify { expect(described_class.new(ProductsIndex).limit(10)).not_to eq(described_class.new(ProductsIndex).limit(20)) }
|
@@ -48,7 +46,7 @@ describe Chewy::Search::Request do
|
|
48
46
|
expect(subject.render)
|
49
47
|
.to match(
|
50
48
|
index: %w[products],
|
51
|
-
type: array_including(%w[product
|
49
|
+
type: array_including(%w[product]),
|
52
50
|
body: {}
|
53
51
|
)
|
54
52
|
end
|
@@ -57,11 +55,11 @@ describe Chewy::Search::Request do
|
|
57
55
|
describe '#inspect' do
|
58
56
|
specify do
|
59
57
|
expect(described_class.new(ProductsIndex).inspect)
|
60
|
-
.to eq('<Chewy::Search::Request {:index=>["products"], :type=>["product"
|
58
|
+
.to eq('<Chewy::Search::Request {:index=>["products"], :type=>["product"], :body=>{}}>')
|
61
59
|
end
|
62
60
|
specify do
|
63
61
|
expect(ProductsIndex.limit(10).inspect)
|
64
|
-
.to eq('<ProductsIndex::Query {:index=>["products"], :type=>["product"
|
62
|
+
.to eq('<ProductsIndex::Query {:index=>["products"], :type=>["product"], :body=>{:size=>10}}>')
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
@@ -151,13 +149,20 @@ describe Chewy::Search::Request do
|
|
151
149
|
end
|
152
150
|
|
153
151
|
describe '#request_cache' do
|
154
|
-
specify { expect(subject.request_cache(true).render
|
155
|
-
specify { expect(subject.request_cache(true).request_cache(false).render
|
156
|
-
specify { expect(subject.request_cache(true).request_cache(nil).render[:
|
152
|
+
specify { expect(subject.request_cache(true).render).to include(request_cache: true) }
|
153
|
+
specify { expect(subject.request_cache(true).request_cache(false).render).to include(request_cache: false) }
|
154
|
+
specify { expect(subject.request_cache(true).request_cache(nil).render[:request_cache]).to be_blank }
|
157
155
|
specify { expect { subject.request_cache(true) }.not_to change { subject.render } }
|
158
156
|
end
|
159
157
|
|
160
|
-
|
158
|
+
describe '#search_type' do
|
159
|
+
specify { expect(subject.search_type('foo').render).to include(search_type: 'foo') }
|
160
|
+
specify { expect(subject.search_type('foo').search_type('bar').render).to include(search_type: 'bar') }
|
161
|
+
specify { expect(subject.search_type('foo').search_type(nil).render[:search_type]).to be_blank }
|
162
|
+
specify { expect { subject.search_type('foo') }.not_to change { subject.render } }
|
163
|
+
end
|
164
|
+
|
165
|
+
%i[preference timeout].each do |name|
|
161
166
|
describe "##{name}" do
|
162
167
|
specify { expect(subject.send(name, :foo).render[:body]).to include(name => 'foo') }
|
163
168
|
specify { expect(subject.send(name, :foo).send(name, :bar).render[:body]).to include(name => 'bar') }
|
@@ -218,10 +223,18 @@ describe Chewy::Search::Request do
|
|
218
223
|
specify { expect { subject.docvalue_fields(:foo) }.not_to change { subject.render } }
|
219
224
|
end
|
220
225
|
|
226
|
+
describe '#indices' do
|
227
|
+
specify { expect(described_class.new(:products).render[:index]).to eq(%w[products]) }
|
228
|
+
specify { expect(subject.indices(:cities).render[:index]).to eq(%w[cities products]) }
|
229
|
+
specify { expect(subject.indices(CitiesIndex, :whatever).render[:index]).to eq(%w[cities products whatever]) }
|
230
|
+
specify { expect(subject.indices([CitiesIndex, :products]).render[:index]).to eq(%w[cities products]) }
|
231
|
+
specify { expect { subject.indices(:cities) }.not_to change { subject.render } }
|
232
|
+
end
|
233
|
+
|
221
234
|
describe '#types' do
|
222
235
|
specify { expect(subject.types(:product).render[:type]).to contain_exactly('product') }
|
223
|
-
specify { expect(subject.types(%i[product city]).types(nil).render[:type]).to match_array(%w[product
|
224
|
-
specify { expect(subject.types(:product).types(:product, :city, :something).render[:type]).to match_array(%w[product
|
236
|
+
specify { expect(subject.types(%i[product city]).types(nil).render[:type]).to match_array(%w[product]) }
|
237
|
+
specify { expect(subject.types(:product).types(:product, :city, :something).render[:type]).to match_array(%w[product]) }
|
225
238
|
specify { expect(subject.types(nil).render[:body]).to be_blank }
|
226
239
|
specify { expect { subject.types(:product) }.not_to change { subject.render } }
|
227
240
|
end
|
@@ -263,14 +276,16 @@ describe Chewy::Search::Request do
|
|
263
276
|
define_type City do
|
264
277
|
field :rating, type: 'integer'
|
265
278
|
end
|
279
|
+
end
|
266
280
|
|
281
|
+
stub_index(:countries) do
|
267
282
|
define_type Country do
|
268
283
|
field :rating, type: 'integer'
|
269
284
|
end
|
270
285
|
end
|
271
286
|
end
|
272
287
|
|
273
|
-
before { PlacesIndex.import!(cities
|
288
|
+
before { PlacesIndex.import!(cities) }
|
274
289
|
|
275
290
|
let(:cities) { Array.new(2) { |i| City.create!(rating: i) } }
|
276
291
|
let(:countries) { Array.new(2) { |i| Country.create!(rating: i + 2) } }
|
@@ -278,14 +293,14 @@ describe Chewy::Search::Request do
|
|
278
293
|
subject { described_class.new(PlacesIndex).order(:rating) }
|
279
294
|
|
280
295
|
describe '#objects' do
|
281
|
-
specify { expect(subject.objects).to eq([*cities
|
296
|
+
specify { expect(subject.objects).to eq([*cities]) }
|
282
297
|
specify { expect(subject.objects.class).to eq(Array) }
|
283
298
|
end
|
284
299
|
|
285
300
|
describe '#load' do
|
286
|
-
specify { expect(subject.load(only: 'city')).to eq([*cities
|
287
|
-
specify { expect(subject.load(only: 'city').map(&:class).uniq).to eq([PlacesIndex::City
|
288
|
-
specify { expect(subject.load(only: 'city').objects).to eq([*cities
|
301
|
+
specify { expect(subject.load(only: 'city')).to eq([*cities]) }
|
302
|
+
specify { expect(subject.load(only: 'city').map(&:class).uniq).to eq([PlacesIndex::City]) }
|
303
|
+
specify { expect(subject.load(only: 'city').objects).to eq([*cities]) }
|
289
304
|
end
|
290
305
|
end
|
291
306
|
|
@@ -372,13 +387,13 @@ describe Chewy::Search::Request do
|
|
372
387
|
end
|
373
388
|
|
374
389
|
context 'integration' do
|
375
|
-
let(:
|
376
|
-
let(:
|
377
|
-
let(:
|
390
|
+
let(:products_count) { 9 }
|
391
|
+
let(:products) { Array.new(products_count) { |i| {id: i.next.to_i, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
|
392
|
+
let(:cities) { Array.new(3) { |i| {id: (i.next + 9).to_i}.stringify_keys! } }
|
393
|
+
let(:countries) { Array.new(3) { |i| {id: (i.next + 12).to_i}.stringify_keys! } }
|
378
394
|
before do
|
379
395
|
ProductsIndex::Product.import!(products.map { |h| double(h) })
|
380
|
-
|
381
|
-
ProductsIndex::Country.import!(countries.map { |h| double(h) })
|
396
|
+
CountriesIndex::Country.import!(countries.map { |h| double(h) })
|
382
397
|
CitiesIndex::City.import!(cities.map { |h| double(h) })
|
383
398
|
end
|
384
399
|
|
@@ -391,18 +406,11 @@ describe Chewy::Search::Request do
|
|
391
406
|
specify { expect(subject.size).to eq(3) }
|
392
407
|
end
|
393
408
|
|
394
|
-
context '
|
395
|
-
subject { described_class.new(
|
396
|
-
|
397
|
-
specify { expect(subject.count).to eq(6) }
|
398
|
-
specify { expect(subject.size).to eq(6) }
|
399
|
-
end
|
400
|
-
|
401
|
-
context 'mixed types' do
|
402
|
-
subject { described_class.new(CitiesIndex, ProductsIndex::Product) }
|
409
|
+
context 'mixed indexes' do
|
410
|
+
subject { described_class.new(CitiesIndex, ProductsIndex) }
|
403
411
|
|
404
|
-
specify { expect(subject.count).to eq(
|
405
|
-
specify { expect(subject.size).to eq(
|
412
|
+
specify { expect(subject.count).to eq(12) }
|
413
|
+
specify { expect(subject.size).to eq(10) } # pagination limit
|
406
414
|
end
|
407
415
|
|
408
416
|
context 'instrumentation' do
|
@@ -415,9 +423,9 @@ describe Chewy::Search::Request do
|
|
415
423
|
expect(outer_payload).to eq(
|
416
424
|
index: ProductsIndex,
|
417
425
|
indexes: [ProductsIndex],
|
418
|
-
request: {index: ['products'], type: %w[product
|
419
|
-
type:
|
420
|
-
types: [ProductsIndex::Product
|
426
|
+
request: {index: ['products'], type: %w[product], body: {query: {match: {name: 'name3'}}}},
|
427
|
+
type: ProductsIndex::Product,
|
428
|
+
types: [ProductsIndex::Product]
|
421
429
|
)
|
422
430
|
end
|
423
431
|
end
|
@@ -429,10 +437,13 @@ describe Chewy::Search::Request do
|
|
429
437
|
describe '#highlight' do
|
430
438
|
specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name).to eq('Name3') }
|
431
439
|
specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name_highlight).to eq('<em>Name3</em>') }
|
440
|
+
specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name_highlights).to eq(['<em>Name3</em>']) }
|
432
441
|
specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first._data['_source']['name']).to eq('Name3') }
|
433
442
|
end
|
434
443
|
|
435
444
|
describe '#suggest' do
|
445
|
+
let(:products_count) { 3 }
|
446
|
+
|
436
447
|
specify do
|
437
448
|
expect(subject.suggest(
|
438
449
|
foo: {
|
@@ -454,7 +465,7 @@ describe Chewy::Search::Request do
|
|
454
465
|
describe '#aggs' do
|
455
466
|
specify do
|
456
467
|
expect(subject.aggs(avg_age: {avg: {field: :age}}).aggs)
|
457
|
-
.to eq('avg_age' => {'value' =>
|
468
|
+
.to eq('avg_age' => {'value' => 50.0})
|
458
469
|
end
|
459
470
|
end
|
460
471
|
|
@@ -474,8 +485,7 @@ describe Chewy::Search::Request do
|
|
474
485
|
specify { expect(subject.count).to eq(9) }
|
475
486
|
specify { expect(subject.limit(6).count).to eq(9) }
|
476
487
|
specify { expect(subject.offset(6).count).to eq(9) }
|
477
|
-
specify { expect(subject.
|
478
|
-
specify { expect(subject.types(:product, :country).count).to eq(6) }
|
488
|
+
specify { expect(subject.indices(:products, CountriesIndex).count).to eq(12) }
|
479
489
|
specify { expect(subject.filter(term: {age: 10}).count).to eq(1) }
|
480
490
|
specify { expect(subject.query(term: {age: 10}).count).to eq(1) }
|
481
491
|
specify { expect(subject.order(nil).count).to eq(9) }
|
@@ -514,7 +524,7 @@ describe Chewy::Search::Request do
|
|
514
524
|
context do
|
515
525
|
before { expect(Chewy.client).to receive(:search).once.and_call_original }
|
516
526
|
|
517
|
-
specify { expect(subject.first).to be_a(ProductsIndex::
|
527
|
+
specify { expect(subject.first).to be_a(ProductsIndex::Product).and have_attributes(id: 9) }
|
518
528
|
specify { expect(subject.first(3).map(&:id)).to eq([9, 8, 7]) }
|
519
529
|
specify { expect(subject.first(10).map(&:id)).to have(9).items }
|
520
530
|
specify { expect(subject.limit(5).first(10).map(&:id)).to have(9).items }
|
@@ -527,7 +537,7 @@ describe Chewy::Search::Request do
|
|
527
537
|
expect(Chewy.client).not_to receive(:search)
|
528
538
|
end
|
529
539
|
|
530
|
-
specify { expect(subject.first).to be_a(ProductsIndex::
|
540
|
+
specify { expect(subject.first).to be_a(ProductsIndex::Product).and have_attributes(id: 9) }
|
531
541
|
specify { expect(subject.first(3).map(&:id)).to eq([9, 8, 7]) }
|
532
542
|
specify { expect(subject.first(10).map(&:id)).to have(9).items }
|
533
543
|
|
@@ -560,7 +570,7 @@ describe Chewy::Search::Request do
|
|
560
570
|
specify { expect { subject.post_filter(match: {name: 'name2'}).find('1', '3') }.to raise_error Chewy::DocumentNotFound, 'Could not find documents for ids: 1 and 3' }
|
561
571
|
|
562
572
|
context 'make sure it returns everything' do
|
563
|
-
let(:
|
573
|
+
let(:products_count) { 12 }
|
564
574
|
before { expect(Chewy.client).not_to receive(:scroll) }
|
565
575
|
|
566
576
|
specify { expect(subject.find((1..12).to_a)).to have(12).items }
|
@@ -577,15 +587,15 @@ describe Chewy::Search::Request do
|
|
577
587
|
|
578
588
|
describe '#pluck' do
|
579
589
|
specify { expect(subject.limit(5).pluck(:_id)).to eq(%w[1 2 3 4 5]) }
|
580
|
-
specify { expect(subject.limit(5).pluck(:_id, :age)).to eq([['1', 10], ['2', 20], ['3', 30], ['4',
|
581
|
-
specify { expect(subject.limit(5).source(:name).pluck(:id, :age)).to eq([[1, 10], [2, 20], [3, 30], [4,
|
590
|
+
specify { expect(subject.limit(5).pluck(:_id, :age)).to eq([['1', 10], ['2', 20], ['3', 30], ['4', 40], ['5', 50]]) }
|
591
|
+
specify { expect(subject.limit(5).source(:name).pluck(:id, :age)).to eq([[1, 10], [2, 20], [3, 30], [4, 40], [5, 50]]) }
|
582
592
|
specify do
|
583
593
|
expect(subject.limit(5).pluck(:_index, :_type, :name)).to eq([
|
584
594
|
%w[products product Name1],
|
585
595
|
%w[products product Name2],
|
586
596
|
%w[products product Name3],
|
587
|
-
[
|
588
|
-
[
|
597
|
+
%w[products product Name4],
|
598
|
+
%w[products product Name5]
|
589
599
|
])
|
590
600
|
end
|
591
601
|
|
@@ -616,24 +626,12 @@ describe Chewy::Search::Request do
|
|
616
626
|
Chewy.client.indices.refresh(index: 'products')
|
617
627
|
end.to change { described_class.new(ProductsIndex).total_count }.from(9).to(7)
|
618
628
|
end
|
619
|
-
specify do
|
620
|
-
expect do
|
621
|
-
subject.types(:product).delete_all
|
622
|
-
Chewy.client.indices.refresh(index: 'products')
|
623
|
-
end.to change { described_class.new(ProductsIndex::Product).total_entries }.from(3).to(0)
|
624
|
-
end
|
625
629
|
specify do
|
626
630
|
expect do
|
627
631
|
subject.delete_all
|
628
632
|
Chewy.client.indices.refresh(index: 'products')
|
629
633
|
end.to change { described_class.new(ProductsIndex).total }.from(9).to(0)
|
630
634
|
end
|
631
|
-
specify do
|
632
|
-
expect do
|
633
|
-
described_class.new(ProductsIndex::City).delete_all
|
634
|
-
Chewy.client.indices.refresh(index: 'products')
|
635
|
-
end.to change { described_class.new(ProductsIndex).total }.from(9).to(6)
|
636
|
-
end
|
637
635
|
|
638
636
|
specify do
|
639
637
|
outer_payload = nil
|
@@ -644,9 +642,9 @@ describe Chewy::Search::Request do
|
|
644
642
|
expect(outer_payload).to eq(
|
645
643
|
index: ProductsIndex,
|
646
644
|
indexes: [ProductsIndex],
|
647
|
-
request: {index: ['products'], type: %w[product
|
648
|
-
type:
|
649
|
-
types: [ProductsIndex::Product
|
645
|
+
request: {index: ['products'], type: %w[product], body: {query: {match: {name: 'name3'}}}, refresh: true},
|
646
|
+
type: ProductsIndex::Product,
|
647
|
+
types: [ProductsIndex::Product]
|
650
648
|
)
|
651
649
|
end
|
652
650
|
|
@@ -659,11 +657,44 @@ describe Chewy::Search::Request do
|
|
659
657
|
expect(outer_payload).to eq(
|
660
658
|
index: ProductsIndex,
|
661
659
|
indexes: [ProductsIndex],
|
662
|
-
request: {index: ['products'], type: %w[product
|
663
|
-
type:
|
664
|
-
types: [ProductsIndex::Product
|
660
|
+
request: {index: ['products'], type: %w[product], body: {query: {match: {name: 'name3'}}}, refresh: false},
|
661
|
+
type: ProductsIndex::Product,
|
662
|
+
types: [ProductsIndex::Product]
|
665
663
|
)
|
666
664
|
end
|
667
665
|
end
|
666
|
+
|
667
|
+
describe '#response=' do
|
668
|
+
let(:query) { ProductsIndex.limit(0) }
|
669
|
+
let(:raw_response) { Chewy.client.search(query.render) }
|
670
|
+
|
671
|
+
it 'wraps and assigns the raw response' do
|
672
|
+
query.response = raw_response
|
673
|
+
expect(query.response).to be_a(Chewy::Search::Response)
|
674
|
+
end
|
675
|
+
end
|
676
|
+
|
677
|
+
describe '#performed?' do
|
678
|
+
let(:query) { ProductsIndex.limit(0) }
|
679
|
+
let(:raw_response) { Chewy.client.search(query.render) }
|
680
|
+
|
681
|
+
it 'is false on a new query' do
|
682
|
+
expect(query.performed?).to eq(false)
|
683
|
+
end
|
684
|
+
|
685
|
+
it 'is true after the search request was issued' do
|
686
|
+
expect do
|
687
|
+
# The `response` method has a side effect of performing unperformed
|
688
|
+
# queries.
|
689
|
+
query.response
|
690
|
+
end.to change(query, :performed?).from(false).to(true)
|
691
|
+
end
|
692
|
+
|
693
|
+
it 'is true after assigning a raw response' do
|
694
|
+
expect do
|
695
|
+
query.response = raw_response
|
696
|
+
end.to change(query, :performed?).from(false).to(true)
|
697
|
+
end
|
698
|
+
end
|
668
699
|
end
|
669
700
|
end
|
@@ -7,12 +7,13 @@ describe Chewy::Search::Response, :orm do
|
|
7
7
|
stub_model(:city)
|
8
8
|
stub_model(:country)
|
9
9
|
|
10
|
-
stub_index(:
|
10
|
+
stub_index(:cities) do
|
11
11
|
define_type City do
|
12
12
|
field :name
|
13
13
|
field :rating, type: 'integer'
|
14
14
|
end
|
15
|
-
|
15
|
+
end
|
16
|
+
stub_index(:countries) do
|
16
17
|
define_type Country do
|
17
18
|
field :name
|
18
19
|
field :rating, type: 'integer'
|
@@ -20,15 +21,18 @@ describe Chewy::Search::Response, :orm do
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
before
|
24
|
+
before do
|
25
|
+
CitiesIndex.import!(cities: cities)
|
26
|
+
CountriesIndex.import!(countries)
|
27
|
+
end
|
24
28
|
|
25
29
|
let(:cities) { Array.new(2) { |i| City.create!(rating: i, name: "city #{i}") } }
|
26
30
|
let(:countries) { Array.new(2) { |i| Country.create!(rating: i + 2, name: "country #{i}") } }
|
27
31
|
|
28
|
-
let(:request) { Chewy::Search::Request.new(
|
32
|
+
let(:request) { Chewy::Search::Request.new(CitiesIndex, CountriesIndex).order(:rating) }
|
29
33
|
let(:raw_response) { request.send(:perform) }
|
30
34
|
let(:load_options) { {} }
|
31
|
-
let(:loader) { Chewy::Search::Loader.new(indexes: [
|
35
|
+
let(:loader) { Chewy::Search::Loader.new(indexes: [CitiesIndex, CountriesIndex], **load_options) }
|
32
36
|
subject { described_class.new(raw_response, loader) }
|
33
37
|
|
34
38
|
describe '#hits' do
|
@@ -59,7 +63,7 @@ describe Chewy::Search::Response, :orm do
|
|
59
63
|
specify { expect(subject.max_score).to be_nil }
|
60
64
|
|
61
65
|
context do
|
62
|
-
let(:request) { Chewy::Search::Request.new(
|
66
|
+
let(:request) { Chewy::Search::Request.new(CitiesIndex).query(range: {rating: {lte: 42}}) }
|
63
67
|
specify { expect(subject.max_score).to eq(1.0) }
|
64
68
|
end
|
65
69
|
end
|
@@ -69,10 +73,13 @@ describe Chewy::Search::Response, :orm do
|
|
69
73
|
|
70
74
|
context do
|
71
75
|
let(:request) do
|
72
|
-
Chewy::Search::Request.new(
|
76
|
+
Chewy::Search::Request.new(CitiesIndex)
|
73
77
|
.query(script: {script: {inline: 'sleep(100); true', lang: 'groovy'}})
|
74
78
|
end
|
75
|
-
specify
|
79
|
+
specify do
|
80
|
+
pending
|
81
|
+
expect(subject.took).to be > 100
|
82
|
+
end
|
76
83
|
end
|
77
84
|
end
|
78
85
|
|
@@ -81,10 +88,13 @@ describe Chewy::Search::Response, :orm do
|
|
81
88
|
|
82
89
|
context do
|
83
90
|
let(:request) do
|
84
|
-
Chewy::Search::Request.new(
|
91
|
+
Chewy::Search::Request.new(CitiesIndex)
|
85
92
|
.query(script: {script: {inline: 'sleep(100); true', lang: 'groovy'}}).timeout('10ms')
|
86
93
|
end
|
87
|
-
specify
|
94
|
+
specify do
|
95
|
+
pending
|
96
|
+
expect(subject.timed_out?).to eq(true)
|
97
|
+
end
|
88
98
|
end
|
89
99
|
end
|
90
100
|
|
@@ -93,7 +103,7 @@ describe Chewy::Search::Response, :orm do
|
|
93
103
|
|
94
104
|
context do
|
95
105
|
let(:request) do
|
96
|
-
Chewy::Search::Request.new(
|
106
|
+
Chewy::Search::Request.new(CitiesIndex).suggest(
|
97
107
|
my_suggestion: {
|
98
108
|
text: 'city country',
|
99
109
|
term: {
|
@@ -117,7 +127,7 @@ describe Chewy::Search::Response, :orm do
|
|
117
127
|
specify { expect(subject.aggs).to eq({}) }
|
118
128
|
|
119
129
|
context do
|
120
|
-
let(:request) { Chewy::Search::Request.new(
|
130
|
+
let(:request) { Chewy::Search::Request.new(CitiesIndex, CountriesIndex).aggs(avg_rating: {avg: {field: :rating}}) }
|
121
131
|
specify { expect(subject.aggs).to eq('avg_rating' => {'value' => 1.5}) }
|
122
132
|
end
|
123
133
|
end
|
@@ -127,7 +137,7 @@ describe Chewy::Search::Response, :orm do
|
|
127
137
|
specify { expect(subject.wrappers).to have(4).items }
|
128
138
|
specify do
|
129
139
|
expect(subject.wrappers.map(&:class).uniq)
|
130
|
-
.to contain_exactly(
|
140
|
+
.to contain_exactly(CitiesIndex::City, CountriesIndex::Country)
|
131
141
|
end
|
132
142
|
specify { expect(subject.wrappers.map(&:_data)).to eq(subject.hits) }
|
133
143
|
|
@@ -149,14 +159,14 @@ describe Chewy::Search::Response, :orm do
|
|
149
159
|
context do
|
150
160
|
let(:raw_response) do
|
151
161
|
{'hits' => {'hits' => [
|
152
|
-
{'_index' => '
|
162
|
+
{'_index' => 'cities',
|
153
163
|
'_type' => 'city',
|
154
164
|
'_id' => '1',
|
155
165
|
'_score' => 1.3,
|
156
166
|
'_source' => {'id' => 2, 'rating' => 0}}
|
157
167
|
]}}
|
158
168
|
end
|
159
|
-
specify { expect(subject.wrappers.first).to be_a(
|
169
|
+
specify { expect(subject.wrappers.first).to be_a(CitiesIndex::City) }
|
160
170
|
specify { expect(subject.wrappers.first.id).to eq(2) }
|
161
171
|
specify { expect(subject.wrappers.first.rating).to eq(0) }
|
162
172
|
specify { expect(subject.wrappers.first._score).to eq(1.3) }
|
@@ -166,14 +176,14 @@ describe Chewy::Search::Response, :orm do
|
|
166
176
|
context do
|
167
177
|
let(:raw_response) do
|
168
178
|
{'hits' => {'hits' => [
|
169
|
-
{'_index' => '
|
179
|
+
{'_index' => 'countries',
|
170
180
|
'_type' => 'country',
|
171
181
|
'_id' => '2',
|
172
182
|
'_score' => 1.2,
|
173
183
|
'_explanation' => {foo: 'bar'}}
|
174
184
|
]}}
|
175
185
|
end
|
176
|
-
specify { expect(subject.wrappers.first).to be_a(
|
186
|
+
specify { expect(subject.wrappers.first).to be_a(CountriesIndex::Country) }
|
177
187
|
specify { expect(subject.wrappers.first.id).to eq('2') }
|
178
188
|
specify { expect(subject.wrappers.first.rating).to be_nil }
|
179
189
|
specify { expect(subject.wrappers.first._score).to eq(1.2) }
|