elasticated 2.5.5 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|