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
@@ -5,23 +5,17 @@ describe Chewy::Search::Request do
|
|
5
5
|
|
6
6
|
before do
|
7
7
|
stub_index(:products) do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
field :age, type: :integer
|
12
|
-
end
|
8
|
+
field :id, type: :integer
|
9
|
+
field :name
|
10
|
+
field :age, type: :integer
|
13
11
|
end
|
14
12
|
|
15
13
|
stub_index(:cities) do
|
16
|
-
|
17
|
-
field :id, type: :integer
|
18
|
-
end
|
14
|
+
field :id, type: :integer
|
19
15
|
end
|
20
16
|
|
21
17
|
stub_index(:countries) do
|
22
|
-
|
23
|
-
field :id, type: :integer
|
24
|
-
end
|
18
|
+
field :id, type: :integer
|
25
19
|
end
|
26
20
|
end
|
27
21
|
|
@@ -31,11 +25,17 @@ describe Chewy::Search::Request do
|
|
31
25
|
specify { expect(described_class.new(ProductsIndex)).to eq(described_class.new(ProductsIndex)) }
|
32
26
|
specify { expect(described_class.new(ProductsIndex)).not_to eq(described_class.new(CitiesIndex)) }
|
33
27
|
specify { expect(described_class.new(ProductsIndex)).not_to eq(described_class.new(ProductsIndex, CitiesIndex)) }
|
34
|
-
specify
|
35
|
-
|
28
|
+
specify do
|
29
|
+
expect(described_class.new(CitiesIndex, ProductsIndex)).to eq(described_class.new(ProductsIndex, CitiesIndex))
|
30
|
+
end
|
31
|
+
specify do
|
32
|
+
expect(described_class.new(ProductsIndex, CitiesIndex)).to eq(described_class.new(CitiesIndex, ProductsIndex))
|
33
|
+
end
|
36
34
|
|
37
35
|
specify { expect(described_class.new(ProductsIndex).limit(10)).to eq(described_class.new(ProductsIndex).limit(10)) }
|
38
|
-
specify
|
36
|
+
specify do
|
37
|
+
expect(described_class.new(ProductsIndex).limit(10)).not_to eq(described_class.new(ProductsIndex).limit(20))
|
38
|
+
end
|
39
39
|
|
40
40
|
specify { expect(ProductsIndex.limit(10)).to eq(ProductsIndex.limit(10)) }
|
41
41
|
specify { expect(ProductsIndex.limit(10)).not_to eq(CitiesIndex.limit(10)) }
|
@@ -46,7 +46,6 @@ describe Chewy::Search::Request do
|
|
46
46
|
expect(subject.render)
|
47
47
|
.to match(
|
48
48
|
index: %w[products],
|
49
|
-
type: array_including(%w[product]),
|
50
49
|
body: {}
|
51
50
|
)
|
52
51
|
end
|
@@ -55,60 +54,113 @@ describe Chewy::Search::Request do
|
|
55
54
|
describe '#inspect' do
|
56
55
|
specify do
|
57
56
|
expect(described_class.new(ProductsIndex).inspect)
|
58
|
-
.to eq('<Chewy::Search::Request {:index=>["products"], :
|
57
|
+
.to eq('<Chewy::Search::Request {:index=>["products"], :body=>{}}>')
|
59
58
|
end
|
60
59
|
specify do
|
61
60
|
expect(ProductsIndex.limit(10).inspect)
|
62
|
-
.to eq('<ProductsIndex::Query {:index=>["products"], :
|
61
|
+
.to eq('<ProductsIndex::Query {:index=>["products"], :body=>{:size=>10}}>')
|
63
62
|
end
|
64
63
|
end
|
65
64
|
|
66
65
|
%i[query post_filter].each do |name|
|
67
66
|
describe "##{name}" do
|
68
|
-
specify
|
67
|
+
specify do
|
68
|
+
expect(subject.send(name, match: {foo: 'bar'}).render[:body])
|
69
|
+
.to include(name => {match: {foo: 'bar'}})
|
70
|
+
end
|
69
71
|
specify { expect(subject.send(name, nil)).to be_a described_class }
|
70
|
-
specify
|
72
|
+
specify do
|
73
|
+
expect(subject.send(name) { match foo: 'bar' }.render[:body])
|
74
|
+
.to include(name => {match: {foo: 'bar'}})
|
75
|
+
end
|
71
76
|
specify do
|
72
77
|
expect(subject.send(name, match: {foo: 'bar'}).send(name) { multi_match foo: 'bar' }.render[:body])
|
73
78
|
.to include(name => {bool: {must: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
74
79
|
end
|
75
80
|
specify { expect { subject.send(name, match: {foo: 'bar'}) }.not_to change { subject.render } }
|
76
81
|
specify do
|
77
|
-
expect(
|
78
|
-
.
|
82
|
+
expect(
|
83
|
+
subject.send(name).should(match: {foo: 'bar'}).send(name).must_not { multi_match foo: 'bar' }.render[:body]
|
84
|
+
).to include(name => {bool: {should: {match: {foo: 'bar'}}, must_not: {multi_match: {foo: 'bar'}}}})
|
79
85
|
end
|
80
86
|
|
81
87
|
context do
|
82
88
|
let(:other_scope) { subject.send(name).should { multi_match foo: 'bar' }.send(name) { match foo: 'bar' } }
|
83
89
|
|
84
90
|
specify do
|
85
|
-
expect(
|
86
|
-
.
|
91
|
+
expect(
|
92
|
+
subject.send(name).not(other_scope).render[:body]
|
93
|
+
).to include(
|
94
|
+
name => {
|
95
|
+
bool: {
|
96
|
+
must_not: {
|
97
|
+
bool: {
|
98
|
+
must: {match: {foo: 'bar'}},
|
99
|
+
should: {multi_match: {foo: 'bar'}}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
)
|
87
105
|
end
|
88
106
|
end
|
89
107
|
end
|
90
108
|
end
|
91
109
|
|
92
110
|
describe '#filter' do
|
93
|
-
specify
|
111
|
+
specify do
|
112
|
+
expect(subject.filter(match: {foo: 'bar'}).render[:body])
|
113
|
+
.to include(query: {bool: {filter: {match: {foo: 'bar'}}}})
|
114
|
+
end
|
94
115
|
specify { expect(subject.filter(nil)).to be_a described_class }
|
95
|
-
specify
|
116
|
+
specify do
|
117
|
+
expect(subject.filter(match: {foo: 'bar'}).render[:body])
|
118
|
+
.to include(query: {bool: {filter: {match: {foo: 'bar'}}}})
|
119
|
+
end
|
96
120
|
specify do
|
97
121
|
expect(subject.filter(match: {foo: 'bar'}).filter { multi_match foo: 'bar' }.render[:body])
|
98
122
|
.to include(query: {bool: {filter: [{match: {foo: 'bar'}}, {multi_match: {foo: 'bar'}}]}})
|
99
123
|
end
|
100
124
|
specify { expect { subject.filter(match: {foo: 'bar'}) }.not_to change { subject.render } }
|
101
125
|
specify do
|
102
|
-
expect(
|
103
|
-
.
|
126
|
+
expect(
|
127
|
+
subject.filter.should(match: {foo: 'bar'}).filter.must_not { multi_match foo: 'bar' }.render[:body]
|
128
|
+
).to include(
|
129
|
+
query: {
|
130
|
+
bool: {
|
131
|
+
filter: {
|
132
|
+
bool: {
|
133
|
+
should: {match: {foo: 'bar'}},
|
134
|
+
must_not: {multi_match: {foo: 'bar'}}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
)
|
104
140
|
end
|
105
141
|
|
106
142
|
context do
|
107
143
|
let(:other_scope) { subject.filter.should { multi_match foo: 'bar' }.filter { match foo: 'bar' } }
|
108
144
|
|
109
145
|
specify do
|
110
|
-
expect(
|
111
|
-
.
|
146
|
+
expect(
|
147
|
+
subject.filter.not(other_scope).render[:body]
|
148
|
+
).to include(
|
149
|
+
query: {
|
150
|
+
bool: {
|
151
|
+
filter: {
|
152
|
+
bool: {
|
153
|
+
must_not: {
|
154
|
+
bool: {
|
155
|
+
must: {match: {foo: 'bar'}},
|
156
|
+
should: {multi_match: {foo: 'bar'}}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
)
|
112
164
|
end
|
113
165
|
end
|
114
166
|
end
|
@@ -125,7 +177,7 @@ describe Chewy::Search::Request do
|
|
125
177
|
describe '#order' do
|
126
178
|
specify { expect(subject.order(:foo).render[:body]).to include(sort: ['foo']) }
|
127
179
|
specify { expect(subject.order(foo: 42).order(nil).render[:body]).to include(sort: ['foo' => 42]) }
|
128
|
-
specify { expect(subject.order(foo: 42).order(foo: 43).render[:body]).to include(sort: ['foo' => 43]) }
|
180
|
+
specify { expect(subject.order(foo: 42).order(foo: 43).render[:body]).to include(sort: [{'foo' => 42}, {'foo' => 43}]) }
|
129
181
|
specify { expect(subject.order(:foo).order(:bar, :baz).render[:body]).to include(sort: %w[foo bar baz]) }
|
130
182
|
specify { expect(subject.order(nil).render[:body]).to be_blank }
|
131
183
|
specify { expect { subject.order(:foo) }.not_to change { subject.render } }
|
@@ -140,7 +192,7 @@ describe Chewy::Search::Request do
|
|
140
192
|
specify { expect { subject.reorder(:foo) }.not_to change { subject.render } }
|
141
193
|
end
|
142
194
|
|
143
|
-
%i[track_scores explain version profile].each do |name|
|
195
|
+
%i[track_scores track_total_hits explain version profile].each do |name|
|
144
196
|
describe "##{name}" do
|
145
197
|
specify { expect(subject.send(name).render[:body]).to include(name => true) }
|
146
198
|
specify { expect(subject.send(name).send(name, false).render[:body]).to be_blank }
|
@@ -162,13 +214,18 @@ describe Chewy::Search::Request do
|
|
162
214
|
specify { expect { subject.search_type('foo') }.not_to change { subject.render } }
|
163
215
|
end
|
164
216
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
217
|
+
describe '#preference' do
|
218
|
+
specify { expect(subject.preference('foo').render).to include(preference: 'foo') }
|
219
|
+
specify { expect(subject.preference('foo').preference('bar').render).to include(preference: 'bar') }
|
220
|
+
specify { expect(subject.preference('foo').preference(nil).render[:preference]).to be_blank }
|
221
|
+
specify { expect { subject.preference('foo') }.not_to change { subject.render } }
|
222
|
+
end
|
223
|
+
|
224
|
+
describe '#timeout' do
|
225
|
+
specify { expect(subject.timeout(:foo).render[:body]).to include(timeout: 'foo') }
|
226
|
+
specify { expect(subject.timeout(:foo).timeout(:bar).render[:body]).to include(timeout: 'bar') }
|
227
|
+
specify { expect(subject.timeout(:foo).timeout(nil).render[:body]).to be_blank }
|
228
|
+
specify { expect { subject.timeout(:foo) }.not_to change { subject.render } }
|
172
229
|
end
|
173
230
|
|
174
231
|
describe '#source' do
|
@@ -176,23 +233,53 @@ describe Chewy::Search::Request do
|
|
176
233
|
specify { expect(subject.source(:foo, :bar).source(nil).render[:body]).to include(_source: %w[foo bar]) }
|
177
234
|
specify { expect(subject.source(%i[foo bar]).source(nil).render[:body]).to include(_source: %w[foo bar]) }
|
178
235
|
specify { expect(subject.source(excludes: :foo).render[:body]).to include(_source: {excludes: %w[foo]}) }
|
179
|
-
specify
|
180
|
-
|
181
|
-
|
236
|
+
specify do
|
237
|
+
expect(subject.source(excludes: :foo).source(excludes: %i[foo bar]).render[:body])
|
238
|
+
.to include(_source: {excludes: %w[foo bar]})
|
239
|
+
end
|
240
|
+
specify do
|
241
|
+
expect(subject.source(excludes: :foo).source(excludes: %i[foo bar]).render[:body])
|
242
|
+
.to include(_source: {excludes: %w[foo bar]})
|
243
|
+
end
|
244
|
+
specify do
|
245
|
+
expect(subject.source(excludes: :foo).source(:bar).render[:body])
|
246
|
+
.to include(_source: {includes: %w[bar], excludes: %w[foo]})
|
247
|
+
end
|
182
248
|
specify { expect(subject.source(excludes: :foo).source(false).render[:body]).to include(_source: false) }
|
183
|
-
specify
|
184
|
-
|
249
|
+
specify do
|
250
|
+
expect(subject.source(excludes: :foo).source(false).source(excludes: :bar).render[:body])
|
251
|
+
.to include(_source: {excludes: %w[foo bar]})
|
252
|
+
end
|
253
|
+
specify do
|
254
|
+
expect(subject.source(excludes: :foo).source(false).source(true).render[:body])
|
255
|
+
.to include(_source: {excludes: %w[foo]})
|
256
|
+
end
|
185
257
|
specify { expect(subject.source(nil).render[:body]).to be_blank }
|
186
258
|
specify { expect { subject.source(:foo) }.not_to change { subject.render } }
|
187
259
|
end
|
188
260
|
|
189
261
|
describe '#stored_fields' do
|
190
262
|
specify { expect(subject.stored_fields(:foo).render[:body]).to include(stored_fields: ['foo']) }
|
191
|
-
specify
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
specify
|
263
|
+
specify do
|
264
|
+
expect(subject.stored_fields(%i[foo bar]).stored_fields(nil).render[:body])
|
265
|
+
.to include(stored_fields: %w[foo bar])
|
266
|
+
end
|
267
|
+
specify do
|
268
|
+
expect(subject.stored_fields(:foo).stored_fields(:foo, :bar).render[:body])
|
269
|
+
.to include(stored_fields: %w[foo bar])
|
270
|
+
end
|
271
|
+
specify do
|
272
|
+
expect(subject.stored_fields(:foo).stored_fields(false).render[:body])
|
273
|
+
.to include(stored_fields: '_none_')
|
274
|
+
end
|
275
|
+
specify do
|
276
|
+
expect(subject.stored_fields(:foo).stored_fields(false).stored_fields(:bar).render[:body])
|
277
|
+
.to include(stored_fields: %w[foo bar])
|
278
|
+
end
|
279
|
+
specify do
|
280
|
+
expect(subject.stored_fields(:foo).stored_fields(false).stored_fields(true).render[:body])
|
281
|
+
.to include(stored_fields: %w[foo])
|
282
|
+
end
|
196
283
|
specify { expect(subject.stored_fields(nil).render[:body]).to be_blank }
|
197
284
|
specify { expect { subject.stored_fields(:foo) }.not_to change { subject.render } }
|
198
285
|
end
|
@@ -200,8 +287,14 @@ describe Chewy::Search::Request do
|
|
200
287
|
%i[script_fields highlight].each do |name|
|
201
288
|
describe "##{name}" do
|
202
289
|
specify { expect(subject.send(name, foo: {bar: 42}).render[:body]).to include(name => {'foo' => {bar: 42}}) }
|
203
|
-
specify
|
204
|
-
|
290
|
+
specify do
|
291
|
+
expect(subject.send(name, foo: {bar: 42}).send(name, moo: {baz: 43}).render[:body])
|
292
|
+
.to include(name => {'foo' => {bar: 42}, 'moo' => {baz: 43}})
|
293
|
+
end
|
294
|
+
specify do
|
295
|
+
expect(subject.send(name, foo: {bar: 42}).send(name, nil).render[:body])
|
296
|
+
.to include(name => {'foo' => {bar: 42}})
|
297
|
+
end
|
205
298
|
specify { expect { subject.send(name, foo: {bar: 42}) }.not_to change { subject.render } }
|
206
299
|
end
|
207
300
|
end
|
@@ -209,16 +302,40 @@ describe Chewy::Search::Request do
|
|
209
302
|
%i[suggest aggs].each do |name|
|
210
303
|
describe "##{name}" do
|
211
304
|
specify { expect(subject.send(name, foo: {bar: 42}).render[:body]).to include(name => {'foo' => {bar: 42}}) }
|
212
|
-
specify
|
213
|
-
|
305
|
+
specify do
|
306
|
+
expect(subject.send(name, foo: {bar: 42}).send(name, moo: {baz: 43}).render[:body])
|
307
|
+
.to include(name => {'foo' => {bar: 42}, 'moo' => {baz: 43}})
|
308
|
+
end
|
309
|
+
specify do
|
310
|
+
expect(subject.send(name, foo: {bar: 42}).send(name, nil).render[:body])
|
311
|
+
.to include(name => {'foo' => {bar: 42}})
|
312
|
+
end
|
313
|
+
specify { expect { subject.send(name, foo: {bar: 42}) }.not_to change { subject.render } }
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
%i[collapse knn].each do |name|
|
318
|
+
describe "##{name}" do
|
319
|
+
specify { expect(subject.send(name, foo: {bar: 42}).render[:body]).to include(name => {'foo' => {bar: 42}}) }
|
320
|
+
specify do
|
321
|
+
expect(subject.send(name, foo: {bar: 42}).send(name, moo: {baz: 43}).render[:body])
|
322
|
+
.to include(name => {'moo' => {baz: 43}})
|
323
|
+
end
|
324
|
+
specify { expect(subject.send(name, foo: {bar: 42}).send(name, nil).render[:body]).to be_blank }
|
214
325
|
specify { expect { subject.send(name, foo: {bar: 42}) }.not_to change { subject.render } }
|
215
326
|
end
|
216
327
|
end
|
217
328
|
|
218
329
|
describe '#docvalue_fields' do
|
219
330
|
specify { expect(subject.docvalue_fields(:foo).render[:body]).to include(docvalue_fields: ['foo']) }
|
220
|
-
specify
|
221
|
-
|
331
|
+
specify do
|
332
|
+
expect(subject.docvalue_fields(%i[foo bar]).docvalue_fields(nil).render[:body])
|
333
|
+
.to include(docvalue_fields: %w[foo bar])
|
334
|
+
end
|
335
|
+
specify do
|
336
|
+
expect(subject.docvalue_fields(:foo).docvalue_fields(:foo, :bar).render[:body])
|
337
|
+
.to include(docvalue_fields: %w[foo bar])
|
338
|
+
end
|
222
339
|
specify { expect(subject.docvalue_fields(nil).render[:body]).to be_blank }
|
223
340
|
specify { expect { subject.docvalue_fields(:foo) }.not_to change { subject.render } }
|
224
341
|
end
|
@@ -231,24 +348,25 @@ describe Chewy::Search::Request do
|
|
231
348
|
specify { expect { subject.indices(:cities) }.not_to change { subject.render } }
|
232
349
|
end
|
233
350
|
|
234
|
-
describe '#types' do
|
235
|
-
specify { expect(subject.types(:product).render[:type]).to contain_exactly('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]) }
|
238
|
-
specify { expect(subject.types(nil).render[:body]).to be_blank }
|
239
|
-
specify { expect { subject.types(:product) }.not_to change { subject.render } }
|
240
|
-
end
|
241
|
-
|
242
351
|
describe '#indices_boost' do
|
243
352
|
specify { expect(subject.indices_boost(foo: 1.2).render[:body]).to include(indices_boost: [{'foo' => 1.2}]) }
|
244
|
-
specify
|
245
|
-
|
353
|
+
specify do
|
354
|
+
expect(subject.indices_boost(foo: 1.2).indices_boost(moo: 1.3).render[:body])
|
355
|
+
.to include(indices_boost: [{'foo' => 1.2}, {'moo' => 1.3}])
|
356
|
+
end
|
357
|
+
specify do
|
358
|
+
expect(subject.indices_boost(foo: 1.2).indices_boost(nil).render[:body])
|
359
|
+
.to include(indices_boost: [{'foo' => 1.2}])
|
360
|
+
end
|
246
361
|
specify { expect { subject.indices_boost(foo: 1.2) }.not_to change { subject.render } }
|
247
362
|
end
|
248
363
|
|
249
364
|
describe '#rescore' do
|
250
365
|
specify { expect(subject.rescore(foo: 42).render[:body]).to include(rescore: [{foo: 42}]) }
|
251
|
-
specify
|
366
|
+
specify do
|
367
|
+
expect(subject.rescore(foo: 42).rescore(moo: 43).render[:body])
|
368
|
+
.to include(rescore: [{foo: 42}, {moo: 43}])
|
369
|
+
end
|
252
370
|
specify { expect(subject.rescore(foo: 42).rescore(nil).render[:body]).to include(rescore: [{foo: 42}]) }
|
253
371
|
specify { expect { subject.rescore(foo: 42) }.not_to change { subject.render } }
|
254
372
|
end
|
@@ -260,9 +378,19 @@ describe Chewy::Search::Request do
|
|
260
378
|
specify { expect { subject.min_score(1.2) }.not_to change { subject.render } }
|
261
379
|
end
|
262
380
|
|
381
|
+
describe '#ignore_unavailable' do
|
382
|
+
specify { expect(subject.ignore_unavailable(true).render).to include(ignore_unavailable: true) }
|
383
|
+
specify { expect(subject.ignore_unavailable(true).ignore_unavailable(false).render).to include(ignore_unavailable: false) }
|
384
|
+
specify { expect(subject.ignore_unavailable(true).ignore_unavailable(nil).render[:ignore_unavailable]).to be_blank }
|
385
|
+
specify { expect { subject.ignore_unavailable(true) }.not_to change { subject.render } }
|
386
|
+
end
|
387
|
+
|
263
388
|
describe '#search_after' do
|
264
389
|
specify { expect(subject.search_after(:foo, :bar).render[:body]).to include(search_after: %i[foo bar]) }
|
265
|
-
specify
|
390
|
+
specify do
|
391
|
+
expect(subject.search_after(%i[foo bar]).search_after(:baz).render[:body])
|
392
|
+
.to include(search_after: [:baz])
|
393
|
+
end
|
266
394
|
specify { expect(subject.search_after(:foo).search_after(nil).render[:body]).to be_blank }
|
267
395
|
specify { expect { subject.search_after(:foo) }.not_to change { subject.render } }
|
268
396
|
end
|
@@ -273,15 +401,13 @@ describe Chewy::Search::Request do
|
|
273
401
|
stub_model(:country)
|
274
402
|
|
275
403
|
stub_index(:places) do
|
276
|
-
|
277
|
-
|
278
|
-
end
|
404
|
+
index_scope City
|
405
|
+
field :rating, type: 'integer'
|
279
406
|
end
|
280
407
|
|
281
408
|
stub_index(:countries) do
|
282
|
-
|
283
|
-
|
284
|
-
end
|
409
|
+
index_scope Country
|
410
|
+
field :rating, type: 'integer'
|
285
411
|
end
|
286
412
|
end
|
287
413
|
|
@@ -299,7 +425,7 @@ describe Chewy::Search::Request do
|
|
299
425
|
|
300
426
|
describe '#load' do
|
301
427
|
specify { expect(subject.load(only: 'city')).to eq([*cities]) }
|
302
|
-
specify { expect(subject.load(only: 'city').map(&:class).uniq).to eq([PlacesIndex
|
428
|
+
specify { expect(subject.load(only: 'city').map(&:class).uniq).to eq([PlacesIndex]) }
|
303
429
|
specify { expect(subject.load(only: 'city').objects).to eq([*cities]) }
|
304
430
|
end
|
305
431
|
end
|
@@ -319,7 +445,9 @@ describe Chewy::Search::Request do
|
|
319
445
|
|
320
446
|
context do
|
321
447
|
let(:first_scope) { subject.query(foo: 'bar').filter.should(moo: 'baz').post_filter.must_not(boo: 'baf').limit(10) }
|
322
|
-
let(:second_scope)
|
448
|
+
let(:second_scope) do
|
449
|
+
subject.filter(foo: 'bar').post_filter.should(moo: 'baz').query.must_not(boo: 'baf').limit(20)
|
450
|
+
end
|
323
451
|
|
324
452
|
describe '#and' do
|
325
453
|
specify do
|
@@ -388,13 +516,17 @@ describe Chewy::Search::Request do
|
|
388
516
|
|
389
517
|
context 'integration' do
|
390
518
|
let(:products_count) { 9 }
|
391
|
-
let(:products)
|
519
|
+
let(:products) do
|
520
|
+
Array.new(products_count) do |i|
|
521
|
+
{id: i.next.to_i, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys!
|
522
|
+
end
|
523
|
+
end
|
392
524
|
let(:cities) { Array.new(3) { |i| {id: (i.next + 9).to_i}.stringify_keys! } }
|
393
525
|
let(:countries) { Array.new(3) { |i| {id: (i.next + 12).to_i}.stringify_keys! } }
|
394
526
|
before do
|
395
|
-
ProductsIndex
|
396
|
-
CountriesIndex
|
397
|
-
CitiesIndex
|
527
|
+
ProductsIndex.import!(products.map { |h| double(h) })
|
528
|
+
CountriesIndex.import!(countries.map { |h| double(h) })
|
529
|
+
CitiesIndex.import!(cities.map { |h| double(h) })
|
398
530
|
end
|
399
531
|
|
400
532
|
specify { expect(subject[0]._data).to be_a Hash }
|
@@ -423,9 +555,7 @@ describe Chewy::Search::Request do
|
|
423
555
|
expect(outer_payload).to eq(
|
424
556
|
index: ProductsIndex,
|
425
557
|
indexes: [ProductsIndex],
|
426
|
-
request: {index: ['products'],
|
427
|
-
type: ProductsIndex::Product,
|
428
|
-
types: [ProductsIndex::Product]
|
558
|
+
request: {index: ['products'], body: {query: {match: {name: 'name3'}}}}
|
429
559
|
)
|
430
560
|
end
|
431
561
|
end
|
@@ -436,9 +566,18 @@ describe Chewy::Search::Request do
|
|
436
566
|
|
437
567
|
describe '#highlight' do
|
438
568
|
specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name).to eq('Name3') }
|
439
|
-
specify
|
440
|
-
|
441
|
-
|
569
|
+
specify do
|
570
|
+
expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name_highlight)
|
571
|
+
.to eq('<em>Name3</em>')
|
572
|
+
end
|
573
|
+
specify do
|
574
|
+
expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name_highlights)
|
575
|
+
.to eq(['<em>Name3</em>'])
|
576
|
+
end
|
577
|
+
specify do
|
578
|
+
expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first._data['_source']['name'])
|
579
|
+
.to eq('Name3')
|
580
|
+
end
|
442
581
|
end
|
443
582
|
|
444
583
|
describe '#suggest' do
|
@@ -524,7 +663,7 @@ describe Chewy::Search::Request do
|
|
524
663
|
context do
|
525
664
|
before { expect(Chewy.client).to receive(:search).once.and_call_original }
|
526
665
|
|
527
|
-
specify { expect(subject.first).to be_a(ProductsIndex
|
666
|
+
specify { expect(subject.first).to be_a(ProductsIndex).and have_attributes(id: 9) }
|
528
667
|
specify { expect(subject.first(3).map(&:id)).to eq([9, 8, 7]) }
|
529
668
|
specify { expect(subject.first(10).map(&:id)).to have(9).items }
|
530
669
|
specify { expect(subject.limit(5).first(10).map(&:id)).to have(9).items }
|
@@ -537,7 +676,7 @@ describe Chewy::Search::Request do
|
|
537
676
|
expect(Chewy.client).not_to receive(:search)
|
538
677
|
end
|
539
678
|
|
540
|
-
specify { expect(subject.first).to be_a(ProductsIndex
|
679
|
+
specify { expect(subject.first).to be_a(ProductsIndex).and have_attributes(id: 9) }
|
541
680
|
specify { expect(subject.first(3).map(&:id)).to eq([9, 8, 7]) }
|
542
681
|
specify { expect(subject.first(10).map(&:id)).to have(9).items }
|
543
682
|
|
@@ -558,16 +697,34 @@ describe Chewy::Search::Request do
|
|
558
697
|
end
|
559
698
|
|
560
699
|
describe '#find' do
|
561
|
-
specify { expect(subject.find('1')).to be_a(ProductsIndex
|
562
|
-
specify { expect(subject.find { |w| w.id == 2 }).to be_a(ProductsIndex
|
700
|
+
specify { expect(subject.find('1')).to be_a(ProductsIndex).and have_attributes(id: 1) }
|
701
|
+
specify { expect(subject.find { |w| w.id == 2 }).to be_a(ProductsIndex).and have_attributes(id: 2) }
|
563
702
|
specify { expect(subject.limit(2).find('1', '3', '7').map(&:id)).to contain_exactly(1, 3, 7) }
|
564
703
|
specify { expect(subject.find(1, 3, 7).map(&:id)).to contain_exactly(1, 3, 7) }
|
565
|
-
specify
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
specify
|
570
|
-
|
704
|
+
specify do
|
705
|
+
expect { subject.find('1', '3', '42') }
|
706
|
+
.to raise_error Chewy::DocumentNotFound, 'Could not find documents for ids: 42'
|
707
|
+
end
|
708
|
+
specify do
|
709
|
+
expect { subject.find(1, 3, 42) }
|
710
|
+
.to raise_error Chewy::DocumentNotFound, 'Could not find documents for ids: 42'
|
711
|
+
end
|
712
|
+
specify do
|
713
|
+
expect { subject.query(match: {name: 'name3'}).find('1', '3') }
|
714
|
+
.to raise_error Chewy::DocumentNotFound, 'Could not find documents for ids: 1'
|
715
|
+
end
|
716
|
+
specify do
|
717
|
+
expect { subject.query(match: {name: 'name2'}).find('1', '3') }
|
718
|
+
.to raise_error Chewy::DocumentNotFound, 'Could not find documents for ids: 1 and 3'
|
719
|
+
end
|
720
|
+
specify do
|
721
|
+
expect { subject.filter(match: {name: 'name2'}).find('1', '3') }
|
722
|
+
.to raise_error Chewy::DocumentNotFound, 'Could not find documents for ids: 1 and 3'
|
723
|
+
end
|
724
|
+
specify do
|
725
|
+
expect { subject.post_filter(match: {name: 'name2'}).find('1', '3') }
|
726
|
+
.to raise_error Chewy::DocumentNotFound, 'Could not find documents for ids: 1 and 3'
|
727
|
+
end
|
571
728
|
|
572
729
|
context 'make sure it returns everything' do
|
573
730
|
let(:products_count) { 12 }
|
@@ -581,21 +738,25 @@ describe Chewy::Search::Request do
|
|
581
738
|
before { expect(Chewy.client).to receive(:scroll).once.and_call_original }
|
582
739
|
|
583
740
|
specify { expect(subject.find((1..9).to_a)).to have(9).items }
|
584
|
-
specify { expect(subject.find((1..9).to_a)).to all be_a(Chewy::
|
741
|
+
specify { expect(subject.find((1..9).to_a)).to all be_a(Chewy::Index) }
|
585
742
|
end
|
586
743
|
end
|
587
744
|
|
588
745
|
describe '#pluck' do
|
589
746
|
specify { expect(subject.limit(5).pluck(:_id)).to eq(%w[1 2 3 4 5]) }
|
590
|
-
specify
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
%w[products
|
747
|
+
specify do
|
748
|
+
expect(subject.limit(5).pluck(:_id, :age)).to eq([['1', 10], ['2', 20], ['3', 30], ['4', 40], ['5', 50]])
|
749
|
+
end
|
750
|
+
specify do
|
751
|
+
expect(subject.limit(5).source(:name).pluck(:id, :age)).to eq([[1, 10], [2, 20], [3, 30], [4, 40], [5, 50]])
|
752
|
+
end
|
753
|
+
specify do
|
754
|
+
expect(subject.limit(5).pluck(:_index, :name)).to eq([
|
755
|
+
%w[products Name1],
|
756
|
+
%w[products Name2],
|
757
|
+
%w[products Name3],
|
758
|
+
%w[products Name4],
|
759
|
+
%w[products Name5]
|
599
760
|
])
|
600
761
|
end
|
601
762
|
|
@@ -642,9 +803,7 @@ describe Chewy::Search::Request do
|
|
642
803
|
expect(outer_payload).to eq(
|
643
804
|
index: ProductsIndex,
|
644
805
|
indexes: [ProductsIndex],
|
645
|
-
request: {index: ['products'],
|
646
|
-
type: ProductsIndex::Product,
|
647
|
-
types: [ProductsIndex::Product]
|
806
|
+
request: {index: ['products'], body: {query: {match: {name: 'name3'}}}, refresh: true}
|
648
807
|
)
|
649
808
|
end
|
650
809
|
|
@@ -657,9 +816,32 @@ describe Chewy::Search::Request do
|
|
657
816
|
expect(outer_payload).to eq(
|
658
817
|
index: ProductsIndex,
|
659
818
|
indexes: [ProductsIndex],
|
660
|
-
request: {index: ['products'],
|
661
|
-
|
662
|
-
|
819
|
+
request: {index: ['products'], body: {query: {match: {name: 'name3'}}}, refresh: false}
|
820
|
+
)
|
821
|
+
end
|
822
|
+
|
823
|
+
it 'delete records asynchronously' do
|
824
|
+
outer_payload = nil
|
825
|
+
ActiveSupport::Notifications.subscribe('delete_query.chewy') do |_name, _start, _finish, _id, payload|
|
826
|
+
outer_payload = payload
|
827
|
+
end
|
828
|
+
subject.query(match: {name: 'name3'}).delete_all(
|
829
|
+
refresh: false,
|
830
|
+
wait_for_completion: false,
|
831
|
+
requests_per_second: 10.0,
|
832
|
+
scroll_size: 2000
|
833
|
+
)
|
834
|
+
expect(outer_payload).to eq(
|
835
|
+
index: ProductsIndex,
|
836
|
+
indexes: [ProductsIndex],
|
837
|
+
request: {
|
838
|
+
index: ['products'],
|
839
|
+
body: {query: {match: {name: 'name3'}}},
|
840
|
+
refresh: false,
|
841
|
+
wait_for_completion: false,
|
842
|
+
requests_per_second: 10.0,
|
843
|
+
scroll_size: 2000
|
844
|
+
}
|
663
845
|
)
|
664
846
|
end
|
665
847
|
end
|