elasticated 2.5.5 → 3.0.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/README.md +35 -2
- data/Rakefile +52 -1
- data/elasticated.gemspec +3 -1
- data/lib/elasticated.rb +20 -24
- data/lib/elasticated/aggregation.rb +3 -6
- data/lib/elasticated/aggregations/date_histogram_aggregation.rb +6 -1
- data/lib/elasticated/aggregations/filter_aggregation.rb +8 -12
- data/lib/elasticated/aggregations/filter_aggregation_evaluator.rb +1 -1
- data/lib/elasticated/aggregations/group_aggregation.rb +14 -11
- data/lib/elasticated/aggregations/range_aggregation.rb +10 -11
- data/lib/elasticated/aggregations/range_aggregation_evaluator.rb +1 -1
- data/lib/elasticated/aggregations/ranges_builder.rb +2 -2
- data/lib/elasticated/aggregations/safe_date_histogram_aggregation.rb +7 -2
- data/lib/elasticated/aggregations/subaggregated.rb +1 -1
- data/lib/elasticated/boolean_clause.rb +4 -3
- data/lib/elasticated/bulk_actions/create_action.rb +14 -0
- data/lib/elasticated/bulk_actions/delete_action.rb +30 -0
- data/lib/elasticated/bulk_actions/index_action.rb +35 -0
- data/lib/elasticated/bulk_actions/standard_action.rb +22 -0
- data/lib/elasticated/bulk_actions/update_action.rb +44 -0
- data/lib/elasticated/bulk_actions/upsert_action.rb +14 -0
- data/lib/elasticated/bulk_request.rb +58 -0
- data/lib/elasticated/bulk_request/response.rb +32 -0
- data/lib/elasticated/bulk_request/response_item.rb +39 -0
- data/lib/elasticated/client.rb +27 -3
- data/lib/elasticated/conditions/custom_condition.rb +3 -3
- data/lib/elasticated/conditions/range_condition.rb +5 -2
- data/lib/elasticated/conditions/script_condition.rb +3 -3
- data/lib/elasticated/conditions/standard_condition.rb +4 -5
- data/lib/elasticated/conditions/term_condition.rb +22 -0
- data/lib/elasticated/conditions/terms_condition.rb +2 -2
- data/lib/elasticated/conditions_builder.rb +19 -4
- data/lib/elasticated/delimiters/date_field_delimiter.rb +21 -12
- data/lib/elasticated/delimiters/standard_field_delimiter.rb +18 -2
- data/lib/elasticated/delimiters/term_field_delimiter.rb +6 -5
- data/lib/elasticated/document.rb +20 -1
- data/lib/elasticated/enum.rb +17 -0
- data/lib/elasticated/index_selector.rb +26 -25
- data/lib/elasticated/mapping.rb +2 -4
- data/lib/elasticated/mapping/builder.rb +3 -2
- data/lib/elasticated/mapping/fields_builder.rb +13 -9
- data/lib/elasticated/mapping/object_builder.rb +38 -4
- data/lib/elasticated/mapping/type_builder.rb +3 -5
- data/lib/elasticated/mixins/block_evaluation.rb +17 -0
- data/lib/elasticated/mixins/clonable.rb +60 -0
- data/lib/elasticated/mixins/configurable.rb +22 -0
- data/lib/elasticated/mixins/inspectionable.rb +16 -0
- data/lib/elasticated/partitioned_repository.rb +24 -18
- data/lib/elasticated/query.rb +27 -21
- data/lib/elasticated/query_aggregations.rb +5 -7
- data/lib/elasticated/query_conditions.rb +6 -3
- data/lib/elasticated/quick.rb +7 -0
- data/lib/elasticated/repository.rb +184 -40
- data/lib/elasticated/repository/intelligent_search.rb +3 -3
- data/lib/elasticated/repository/normal_search.rb +2 -2
- data/lib/elasticated/repository/resumable_search.rb +5 -5
- data/lib/elasticated/repository/scan_scroll_search.rb +4 -4
- data/lib/elasticated/repository/scroll_search.rb +3 -3
- data/lib/elasticated/repository/search.rb +7 -0
- data/lib/elasticated/repository/single_page_search.rb +1 -1
- data/lib/elasticated/results.rb +14 -0
- data/lib/version.rb +18 -25
- data/spec/aggregation_spec.rb +95 -16
- data/spec/bulk_request_spec.rb +158 -0
- data/spec/date_field_delimiter_spec.rb +50 -6
- data/spec/document_spec.rb +1 -5
- data/spec/integration_spec.rb +7 -7
- data/spec/mapping_spec.rb +128 -8
- data/spec/partitioned_repository_spec.rb +218 -0
- data/spec/query_conditions_spec.rb +98 -45
- data/spec/query_spec.rb +21 -28
- data/spec/repository_spec.rb +245 -0
- data/spec/results_spec.rb +0 -4
- data/spec/sample_responses/elasticsearch_bulk_response_1.json +35 -0
- data/spec/sample_responses/elasticsearch_bulk_response_2.json +20 -0
- data/spec/sample_responses/elasticsearch_count_1.json +8 -0
- data/spec/sample_responses/elasticsearch_count_2.json +8 -0
- data/spec/sample_responses/elasticsearch_get_response_1.json +10 -0
- data/spec/sample_responses/elasticsearch_get_response_2.json +6 -0
- data/spec/{elasticsearch_hit_1.json → sample_responses/elasticsearch_hit_1.json} +0 -0
- data/spec/sample_responses/elasticsearch_mget_response_1.json +25 -0
- data/spec/{elasticsearch_response_1.json → sample_responses/elasticsearch_response_1.json} +0 -0
- data/spec/{elasticsearch_response_2.json → sample_responses/elasticsearch_response_2.json} +0 -0
- data/spec/{elasticsearch_top_hits_response.json → sample_responses/elasticsearch_top_hits_response.json} +0 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/spec_helper/fake_index_selector.rb +27 -0
- data/spec/term_field_delimiter_spec.rb +8 -8
- metadata +80 -26
- data/lib/elasticated/block_evaluation.rb +0 -15
- data/lib/elasticated/clonable.rb +0 -58
- data/lib/elasticated/configurable.rb +0 -20
- data/lib/elasticated/date_delimiter_factory.rb +0 -123
- data/lib/elasticated/delimiter_visitor.rb +0 -53
- data/lib/elasticated/inspectionable.rb +0 -9
- data/lib/elasticated/strategy_params_for_query_service.rb +0 -14
- data/lib/elasticated/term_delimiter_factory.rb +0 -73
- data/spec/delimiter_factory_spec.rb +0 -399
- data/spec/strategy_params_for_query_service_spec.rb +0 -387
@@ -13,20 +13,26 @@ module Elasticated
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should build a 'terms' condition" do
|
16
|
-
qc.
|
17
|
-
expected_result = { terms: { field: [:
|
16
|
+
qc.terms :field, [:value1, :value2]
|
17
|
+
expected_result = { terms: { field: [:value1, :value2] } }
|
18
|
+
expect(qc.build).to eq expected_result
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should build a 'terms' condition (with the 'equal' alias)" do
|
22
|
+
qc.equal :field, [:value1, :value2]
|
23
|
+
expected_result = { terms: { field: [:value1, :value2] } }
|
18
24
|
expect(qc.build).to eq expected_result
|
19
25
|
end
|
20
26
|
|
21
27
|
it "should build a 'terms' condition (with params)" do
|
22
|
-
qc.
|
23
|
-
expected_result = { terms: { field: [:
|
28
|
+
qc.terms :field, [:value1, :value2], execution: :bool, _cache: false
|
29
|
+
expected_result = { terms: { field: [:value1, :value2], execution: :bool, _cache: false } }
|
24
30
|
expect(qc.build).to eq expected_result
|
25
31
|
end
|
26
32
|
|
27
33
|
it "should build a 'must_not>terms' condition" do
|
28
|
-
qc.not_equal :field, :
|
29
|
-
expected_result = { bool: { must_not: [ { terms: { field: [:
|
34
|
+
qc.not_equal :field, [:value1, :value2]
|
35
|
+
expected_result = { bool: { must_not: [ { terms: { field: [:value1, :value2] } } ] } }
|
30
36
|
expect(qc.build).to eq expected_result
|
31
37
|
end
|
32
38
|
|
@@ -66,6 +72,12 @@ module Elasticated
|
|
66
72
|
expect(qc.build).to eq expected_result
|
67
73
|
end
|
68
74
|
|
75
|
+
it "should build a 'between' condition (using the 'range' alias)" do
|
76
|
+
qc.range :field, :min_value, :max_value
|
77
|
+
expected_result = { range: { field: { gte: :min_value, lte: :max_value } } }
|
78
|
+
expect(qc.build).to eq expected_result
|
79
|
+
end
|
80
|
+
|
69
81
|
it "should build a 'greater_than' condition" do
|
70
82
|
qc.greater_than :field, :min_value
|
71
83
|
expected_result = { range: { field: { gt: :min_value } } }
|
@@ -122,50 +134,32 @@ module Elasticated
|
|
122
134
|
|
123
135
|
it "should build a 'nested' condition" do
|
124
136
|
qc.nested :hash do |n|
|
125
|
-
n.
|
137
|
+
n.term :field, :value
|
126
138
|
end
|
127
|
-
expected_result = { nested: { path: :hash, filter: {
|
139
|
+
expected_result = { nested: { path: :hash, filter: { term: { field: :value } } } }
|
128
140
|
expect(qc.build).to eq expected_result
|
129
141
|
end
|
130
142
|
|
131
143
|
it "should build a 'nested' condition (with params)" do
|
132
144
|
qc.nested :hash, _cache: true do |n|
|
133
|
-
n.
|
145
|
+
n.term :field, :value
|
134
146
|
end
|
135
|
-
expected_result = { nested: { path: :hash, _cache: true, filter: {
|
147
|
+
expected_result = { nested: { path: :hash, _cache: true, filter: { term: { field: :value } } } }
|
136
148
|
expect(qc.build).to eq expected_result
|
137
149
|
end
|
138
150
|
|
139
|
-
# it "should build a 'should_equal' condition" do
|
140
|
-
# qc.should_equal :field, :value
|
141
|
-
# expected_result = { bool: { should: [ { terms: { field: [:value] } } ] } }
|
142
|
-
# expect(qc.build).to eq expected_result
|
143
|
-
# end
|
144
|
-
|
145
|
-
# it "should build a 'should_wildcard' condition" do
|
146
|
-
# qc.should_wildcard :field, 'regex'
|
147
|
-
# expected_result = { bool: { should: [ { wildcard: { field: 'regex' } } ] } }
|
148
|
-
# expect(qc.build).to eq expected_result
|
149
|
-
# end
|
150
|
-
|
151
|
-
# it "should build a 'should_with' condition" do
|
152
|
-
# qc.should_with :field
|
153
|
-
# expected_result = { bool: { should: [ { wildcard: { field: '*' } } ] } }
|
154
|
-
# expect(qc.build).to eq expected_result
|
155
|
-
# end
|
156
|
-
|
157
151
|
it "should build a 'bool>must' condition" do
|
158
152
|
qc.exists :field
|
159
|
-
qc.
|
160
|
-
expected_result = { bool: { must: [ { exists: { field: :field } }, {
|
153
|
+
qc.term :field, :value
|
154
|
+
expected_result = { bool: { must: [ { exists: { field: :field } }, { term: { field: :value } } ] } }
|
161
155
|
expect(qc.build).to eq expected_result
|
162
156
|
end
|
163
157
|
|
164
158
|
it "should build a 'bool>must' cached condition" do
|
165
159
|
qc.exists :field
|
166
|
-
qc.
|
160
|
+
qc.term :field, :value
|
167
161
|
qc.cache
|
168
|
-
expected_result = { bool: { must: [ { exists: { field: :field } }, {
|
162
|
+
expected_result = { bool: { must: [ { exists: { field: :field } }, { term: { field: :value } } ], _cache: true } }
|
169
163
|
expect(qc.build).to eq expected_result
|
170
164
|
end
|
171
165
|
|
@@ -175,9 +169,9 @@ module Elasticated
|
|
175
169
|
qc.should{ equal :field_three, :value_three }
|
176
170
|
qc.minimum_should_match 2
|
177
171
|
expected_result = { bool: {
|
178
|
-
must: [ {
|
179
|
-
must_not: [ {
|
180
|
-
should: [ {
|
172
|
+
must: [ {term: { field_one: :value_one } } ],
|
173
|
+
must_not: [ { term: { field_two: :value_two } } ],
|
174
|
+
should: [ { term: { field_three: :value_three } } ],
|
181
175
|
minimum_should_match: 2
|
182
176
|
} }
|
183
177
|
expect(qc.build).to eq expected_result
|
@@ -190,11 +184,11 @@ module Elasticated
|
|
190
184
|
expected_result = {
|
191
185
|
bool: {
|
192
186
|
must: [
|
193
|
-
{
|
187
|
+
{ term: { age: 19 } }
|
194
188
|
],
|
195
189
|
should: [
|
196
|
-
{
|
197
|
-
{
|
190
|
+
{ term: { name: 'Pablo' } },
|
191
|
+
{ term: { name: 'Santiago' } }
|
198
192
|
]
|
199
193
|
}
|
200
194
|
}
|
@@ -213,13 +207,13 @@ module Elasticated
|
|
213
207
|
expected_result = {
|
214
208
|
bool: {
|
215
209
|
should: [
|
216
|
-
{
|
217
|
-
{
|
210
|
+
{ term: { first_name: 'Pablo' } },
|
211
|
+
{ term: { last_name: 'Fernandez' } },
|
218
212
|
{
|
219
213
|
bool: {
|
220
214
|
must: [
|
221
|
-
{
|
222
|
-
{
|
215
|
+
{ term: { age: 24 } },
|
216
|
+
{ term: { country: 'Argentina' } }
|
223
217
|
]
|
224
218
|
}
|
225
219
|
}
|
@@ -242,14 +236,73 @@ module Elasticated
|
|
242
236
|
qc.not_equal :field_five, :value_five
|
243
237
|
qc.should{ equal :field_six, :value_six }
|
244
238
|
expected_result = { bool: {
|
245
|
-
must: [ {
|
246
|
-
must_not: [ {
|
247
|
-
should: [ {
|
239
|
+
must: [ {term: { field_one: :value_one } } ],
|
240
|
+
must_not: [ { term: { field_two: :value_two } } ],
|
241
|
+
should: [ { term: { field_three: :value_three } } ]
|
248
242
|
} }
|
249
243
|
expect(new_qc.build).to eq expected_result
|
250
244
|
end
|
251
245
|
|
252
246
|
end
|
253
247
|
|
248
|
+
describe "the term delimiter" do
|
249
|
+
|
250
|
+
let :delimiter do
|
251
|
+
Delimiters::TermFieldDelimiter.new field: :account_id, as: :account
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should not delimit anything" do
|
255
|
+
qc.equal :other_field, 68
|
256
|
+
qc.fill_delimiter delimiter
|
257
|
+
params = delimiter.build_strategy_params
|
258
|
+
expect(params).to be_empty
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should delimit a single condition" do
|
262
|
+
qc.equal :account_id, 68
|
263
|
+
qc.fill_delimiter delimiter
|
264
|
+
params = delimiter.build_strategy_params
|
265
|
+
expect(params).to eq account: [68]
|
266
|
+
end
|
267
|
+
|
268
|
+
it "should delimit by multiple conditions (part 1)" do
|
269
|
+
qc.equal :account_id, [68, 31]
|
270
|
+
qc.fill_delimiter delimiter
|
271
|
+
params = delimiter.build_strategy_params
|
272
|
+
expect(params).to eq account: [68, 31]
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should delimit a multiple conditions (part 2)" do
|
276
|
+
qc.equal :account_id, 68
|
277
|
+
qc.equal :account_id, 31
|
278
|
+
qc.fill_delimiter delimiter
|
279
|
+
params = delimiter.build_strategy_params
|
280
|
+
expect(params).to eq account: [68, 31]
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should delimit by nested conditions" do
|
284
|
+
qc.equal :account_id, 68
|
285
|
+
qc.bool do
|
286
|
+
equal :account_id, 31
|
287
|
+
end
|
288
|
+
qc.fill_delimiter delimiter
|
289
|
+
params = delimiter.build_strategy_params
|
290
|
+
expect(params).to eq account: [68, 31]
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should delimit only by the 'must' part of nested conditions" do
|
294
|
+
qc.equal :account_id, 68
|
295
|
+
qc.bool do
|
296
|
+
must{ equal :account_id, 31 }
|
297
|
+
must_not{ equal :account_id, 85 }
|
298
|
+
should{ equal :account_id, 58 }
|
299
|
+
end
|
300
|
+
qc.fill_delimiter delimiter
|
301
|
+
params = delimiter.build_strategy_params
|
302
|
+
expect(params).to eq account: [68, 31]
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
254
307
|
end
|
255
308
|
end
|
data/spec/query_spec.rb
CHANGED
@@ -67,16 +67,6 @@ module Elasticated
|
|
67
67
|
|
68
68
|
describe "the build method (over other fields)" do
|
69
69
|
|
70
|
-
it "should build a 'match_all' query sorted by a custom hash" do
|
71
|
-
my_custom_hash = { any_key: 'any_value' }
|
72
|
-
q.custom_sort(my_custom_hash)
|
73
|
-
expected_result = {
|
74
|
-
query: { match_all: {} },
|
75
|
-
sort: [my_custom_hash]
|
76
|
-
}
|
77
|
-
expect(q.build).to eq expected_result
|
78
|
-
end
|
79
|
-
|
80
70
|
it "should build a 'match_all' query sorted by a single field" do
|
81
71
|
q.sort :field
|
82
72
|
expected_result = {
|
@@ -104,16 +94,6 @@ module Elasticated
|
|
104
94
|
expect(q.build).to eq expected_result
|
105
95
|
end
|
106
96
|
|
107
|
-
it "should build a 'match_all' query sorted by a custom script" do
|
108
|
-
my_script_hash = { script: "my_script", type: "my_type" }
|
109
|
-
q.sort_by_script(my_script_hash)
|
110
|
-
expected_result = {
|
111
|
-
query: { match_all: {} },
|
112
|
-
sort: [ { _script: my_script_hash } ]
|
113
|
-
}
|
114
|
-
expect(q.build).to eq expected_result
|
115
|
-
end
|
116
|
-
|
117
97
|
it "should build a 'match_all' query sorted randomly" do
|
118
98
|
q.sort_randomly
|
119
99
|
expected_result = {
|
@@ -168,6 +148,15 @@ module Elasticated
|
|
168
148
|
expect(q.build).to eq expected_result
|
169
149
|
end
|
170
150
|
|
151
|
+
it "should build a 'match_all' query returning no source" do
|
152
|
+
q.source false
|
153
|
+
expected_result = {
|
154
|
+
query: { match_all: {} },
|
155
|
+
_source: false
|
156
|
+
}
|
157
|
+
expect(q.build).to eq expected_result
|
158
|
+
end
|
159
|
+
|
171
160
|
it "should build an aggregated search query" do
|
172
161
|
q.aggregations{ group :field, size: 5 }
|
173
162
|
expect(q.build).to eq query: { match_all: {} },
|
@@ -191,7 +180,7 @@ module Elasticated
|
|
191
180
|
|
192
181
|
it "should raise trying to build a non-aggregated query as an aggregated one" do
|
193
182
|
q.size(10).sort(:field).source(:field)
|
194
|
-
expect{ q.build_for_aggregations }.to raise_error
|
183
|
+
expect{ q.build_for_aggregations }.to raise_error RuntimeError
|
195
184
|
end
|
196
185
|
|
197
186
|
it "should build a 'top hits' query" do
|
@@ -208,12 +197,14 @@ module Elasticated
|
|
208
197
|
it "should build a complex query" do
|
209
198
|
q.filter do
|
210
199
|
equal :last_name, 'Fernandez'
|
200
|
+
equal :age, [23, 24]
|
211
201
|
should do
|
212
202
|
equal :first_name, 'Pablo'
|
213
203
|
bool do
|
214
204
|
must do
|
215
205
|
equal :first_name, 'Tomas'
|
216
206
|
equal :second_name, 'Agustin'
|
207
|
+
range :age, '2001-01-01', now
|
217
208
|
end
|
218
209
|
end
|
219
210
|
end
|
@@ -223,8 +214,8 @@ module Elasticated
|
|
223
214
|
not_equal :city, 'CABA'
|
224
215
|
end
|
225
216
|
q.aggregations do
|
226
|
-
|
227
|
-
|
217
|
+
terms :entry_type, size: 5 do
|
218
|
+
terms :entry_name, compact: true
|
228
219
|
end
|
229
220
|
end
|
230
221
|
q.size 20
|
@@ -239,15 +230,17 @@ module Elasticated
|
|
239
230
|
filter: {
|
240
231
|
bool: {
|
241
232
|
must: [
|
242
|
-
{
|
233
|
+
{ term: { last_name: 'Fernandez' } },
|
234
|
+
{ terms: { age: [23, 24] } }
|
243
235
|
],
|
244
236
|
should: [
|
245
|
-
{
|
237
|
+
{ term: { first_name: 'Pablo' } },
|
246
238
|
{
|
247
239
|
bool: {
|
248
240
|
must: [
|
249
|
-
{
|
250
|
-
{
|
241
|
+
{ term: { first_name: 'Tomas' } },
|
242
|
+
{ term: { second_name: 'Agustin' } },
|
243
|
+
{ range: { age: { gte: '2001-01-01', lte: 'now' } } }
|
251
244
|
]
|
252
245
|
}
|
253
246
|
}
|
@@ -258,7 +251,7 @@ module Elasticated
|
|
258
251
|
query: {
|
259
252
|
bool: {
|
260
253
|
must_not: [
|
261
|
-
{
|
254
|
+
{ term: { city: 'CABA' } }
|
262
255
|
]
|
263
256
|
}
|
264
257
|
}
|
@@ -0,0 +1,245 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
module Elasticated
|
4
|
+
describe Repository do
|
5
|
+
|
6
|
+
let(:transport){ double }
|
7
|
+
let(:repository){ Repository.new }
|
8
|
+
let(:query){ Query.new }
|
9
|
+
|
10
|
+
before :each do
|
11
|
+
allow(repository.client).to receive(:transport).and_return transport
|
12
|
+
end
|
13
|
+
|
14
|
+
def expect_source_preparation
|
15
|
+
expect(repository).to receive(:prepare_source).once.and_call_original
|
16
|
+
end
|
17
|
+
|
18
|
+
def expect_document_preparation
|
19
|
+
expect_source_preparation
|
20
|
+
expect(repository).to receive(:params_for_document).twice.and_call_original
|
21
|
+
end
|
22
|
+
|
23
|
+
def expect_query_preparation
|
24
|
+
expect(repository).to receive(:params_for_query).once.and_call_original
|
25
|
+
end
|
26
|
+
|
27
|
+
def expect_percolator_preparation
|
28
|
+
expect(repository).to receive(:params_for_percolator).once.and_call_original
|
29
|
+
end
|
30
|
+
|
31
|
+
def expect_ids_preparation
|
32
|
+
expect(repository).to receive(:params_for_ids).once.and_call_original
|
33
|
+
end
|
34
|
+
|
35
|
+
def expect_served_document_preparation(times=nil)
|
36
|
+
times ||= :once
|
37
|
+
expect(repository).to receive(:restore_source).send(times).and_call_original
|
38
|
+
end
|
39
|
+
|
40
|
+
context "on a query" do
|
41
|
+
|
42
|
+
it "should return the only page of results" do
|
43
|
+
response = open_response 'elasticsearch_response_1'
|
44
|
+
expect(transport).to receive(:search).with(body: query.build_for_search).and_return response
|
45
|
+
expect_query_preparation
|
46
|
+
results = repository.execute_search query, as: :single_page
|
47
|
+
expect(results.count).to eq 1
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should delete all matching documents" do
|
51
|
+
expect(transport).to receive(:delete_by_query).with(body: query.build_for_count)
|
52
|
+
expect_query_preparation
|
53
|
+
repository.delete_by query
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should return the qty of matching documents" do
|
57
|
+
response = open_response 'elasticsearch_count_1'
|
58
|
+
expect(transport).to receive(:count).with(body: query.build_for_count).and_return response
|
59
|
+
result = repository.execute_count query
|
60
|
+
expect(result).to eq 15
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return true on a 'exists?' query with hits > 0" do
|
64
|
+
response = open_response 'elasticsearch_count_1'
|
65
|
+
expect(transport).to receive(:count).with(body: query.build_for_count).and_return response
|
66
|
+
result = repository.exists? query
|
67
|
+
expect(result).to eq true
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return false on a 'exists?' query with hits = 0" do
|
71
|
+
response = open_response 'elasticsearch_count_2'
|
72
|
+
expect(transport).to receive(:count).with(body: query.build_for_count).and_return response
|
73
|
+
result = repository.exists? query
|
74
|
+
expect(result).to eq false
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
context "on an indexation" do
|
80
|
+
|
81
|
+
before :each do
|
82
|
+
expect_document_preparation
|
83
|
+
end
|
84
|
+
|
85
|
+
let(:source){ { 'name' => 'Pablo' } }
|
86
|
+
let(:document){ Document.create id: 'my_id', type: 'my_type', index: 'my_index', source: source }
|
87
|
+
|
88
|
+
it "should index the given document" do
|
89
|
+
expect(transport).to receive(:index).with(id: 'my_id', type: 'my_type', index: 'my_index', body: source)
|
90
|
+
repository.index_document document
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
context "on an update" do
|
96
|
+
|
97
|
+
before :each do
|
98
|
+
expect_source_preparation
|
99
|
+
end
|
100
|
+
|
101
|
+
let(:source){ { 'my_field' => 'my_value' } }
|
102
|
+
|
103
|
+
it "should update the given document" do
|
104
|
+
expect(transport).to receive(:update).with(id: 'my_id', type: 'my_type', index: 'my_index', body: { doc: source })
|
105
|
+
repository.update_document 'my_id', type: 'my_type', index: 'my_index', source: source
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
context "on a single document action" do
|
111
|
+
|
112
|
+
before :each do
|
113
|
+
expect_ids_preparation
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should get some document by id" do
|
117
|
+
response = open_response 'elasticsearch_get_response_1'
|
118
|
+
expect(transport).to receive(:get).with(id: 'my_doc_id').and_return response
|
119
|
+
expect_served_document_preparation
|
120
|
+
result = repository.get_document 'my_doc_id'
|
121
|
+
expect(result).to be_a Document
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should get some document by id and return nil if isnt present" do
|
125
|
+
response = open_response 'elasticsearch_get_response_2'
|
126
|
+
expect(transport).to receive(:get).with(id: 'my_doc_id').and_return response
|
127
|
+
result = repository.get_document 'my_doc_id'
|
128
|
+
expect(result).to be_nil
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should delete some document by id" do
|
132
|
+
expect(transport).to receive(:delete).with(id: 'my_doc_id')
|
133
|
+
repository.delete_document 'my_doc_id'
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should get multiple documents by id" do
|
137
|
+
response = open_response 'elasticsearch_mget_response_1'
|
138
|
+
expect(transport).to receive(:mget).with(body: { ids: ['id1', 'id2'] }).and_return response
|
139
|
+
expect_served_document_preparation :twice
|
140
|
+
result = repository.get_document ['id1', 'id2']
|
141
|
+
expect(result.count).to eq 2
|
142
|
+
expect(result[0]).to be_a Document
|
143
|
+
expect(result[1]).to be_a Document
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
context "on a percolation" do
|
149
|
+
|
150
|
+
before :each do
|
151
|
+
expect_percolator_preparation
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should create a percolator" do
|
155
|
+
expect(transport).to receive(:index).with(index: 'my_index', type: '.percolator', id: 'my_id', body: { query: query.build_for_count })
|
156
|
+
expect_query_preparation
|
157
|
+
repository.create_percolator query, index: 'my_index', id: 'my_id'
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should check a percolator" do
|
161
|
+
document = Document.new user: 'Pablo'
|
162
|
+
expect(transport).to receive(:percolate).with(index: 'my_index', type: 'my_type', body: { doc: { user: 'Pablo' } })
|
163
|
+
expect_document_preparation
|
164
|
+
repository.percolate_document document, index: 'my_index', type: 'my_type'
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
context "on a bulk request" do
|
170
|
+
|
171
|
+
let :source do
|
172
|
+
{ some_field: 'some_value' }
|
173
|
+
end
|
174
|
+
|
175
|
+
let :document do
|
176
|
+
Document.create do |doc|
|
177
|
+
doc.id = 2
|
178
|
+
doc.type = 'post'
|
179
|
+
doc.index = 'insights'
|
180
|
+
doc.source = source
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
let :bulk_request do
|
185
|
+
repository.prepare_bulk do |br|
|
186
|
+
br.delete_document 2, type: 'post', index: 'insights'
|
187
|
+
br.create_document document
|
188
|
+
br.update_document 2, type: 'post', index: 'insights', source: source
|
189
|
+
br.index_document document
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should execute the correct json" do
|
194
|
+
expect(transport).to receive(:bulk).with body: [
|
195
|
+
{ delete: { _index: 'insights', _type: 'post', _id: 2 } },
|
196
|
+
{ create: { _index: 'insights', _type: 'post', _id: 2 } },
|
197
|
+
{ some_field: 'some_value' },
|
198
|
+
{ update: { _index: 'insights', _type: 'post', _id: 2 } },
|
199
|
+
{ doc: { some_field: 'some_value' } },
|
200
|
+
{ index: { _index: 'insights', _type: 'post', _id: 2 } },
|
201
|
+
{ some_field: 'some_value' }
|
202
|
+
]
|
203
|
+
expect(bulk_request).to receive(:parse)
|
204
|
+
repository.execute_bulk bulk_request
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should forward the 'parse' responsability" do
|
208
|
+
response = open_response 'elasticsearch_bulk_response_1'
|
209
|
+
expect(transport).to receive(:bulk).and_return response
|
210
|
+
expect(bulk_request).to receive(:parse).with(response)
|
211
|
+
repository.execute_bulk bulk_request
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
context "on invalid actions" do
|
217
|
+
|
218
|
+
it "should raise on an empty get" do
|
219
|
+
expect{ repository.get_document [] }.to raise_error RuntimeError
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should raise on an multiple delete" do
|
223
|
+
expect{ repository.delete_document ['id1', 'id2'] }.to raise_error RuntimeError
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should raise if no document source is specified" do
|
227
|
+
expect{ repository.update_document 'my_id', type: 'my_type', index: 'my_index' }.to raise_error RuntimeError
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should raise if no index is specified" do
|
231
|
+
expect{ repository.update_document 'my_id', type: 'my_type', source: Hash.new }.to raise_error RuntimeError
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should raise if no type is specified" do
|
235
|
+
expect{ repository.update_document 'my_id', index: 'my_index', source: Hash.new }.to raise_error RuntimeError
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should raise if no document id is specified" do
|
239
|
+
expect{ repository.update_document type: 'my_type', index: 'my_index', source: Hash.new }.to raise_error RuntimeError
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
end
|