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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -2
  3. data/Rakefile +52 -1
  4. data/elasticated.gemspec +3 -1
  5. data/lib/elasticated.rb +20 -24
  6. data/lib/elasticated/aggregation.rb +3 -6
  7. data/lib/elasticated/aggregations/date_histogram_aggregation.rb +6 -1
  8. data/lib/elasticated/aggregations/filter_aggregation.rb +8 -12
  9. data/lib/elasticated/aggregations/filter_aggregation_evaluator.rb +1 -1
  10. data/lib/elasticated/aggregations/group_aggregation.rb +14 -11
  11. data/lib/elasticated/aggregations/range_aggregation.rb +10 -11
  12. data/lib/elasticated/aggregations/range_aggregation_evaluator.rb +1 -1
  13. data/lib/elasticated/aggregations/ranges_builder.rb +2 -2
  14. data/lib/elasticated/aggregations/safe_date_histogram_aggregation.rb +7 -2
  15. data/lib/elasticated/aggregations/subaggregated.rb +1 -1
  16. data/lib/elasticated/boolean_clause.rb +4 -3
  17. data/lib/elasticated/bulk_actions/create_action.rb +14 -0
  18. data/lib/elasticated/bulk_actions/delete_action.rb +30 -0
  19. data/lib/elasticated/bulk_actions/index_action.rb +35 -0
  20. data/lib/elasticated/bulk_actions/standard_action.rb +22 -0
  21. data/lib/elasticated/bulk_actions/update_action.rb +44 -0
  22. data/lib/elasticated/bulk_actions/upsert_action.rb +14 -0
  23. data/lib/elasticated/bulk_request.rb +58 -0
  24. data/lib/elasticated/bulk_request/response.rb +32 -0
  25. data/lib/elasticated/bulk_request/response_item.rb +39 -0
  26. data/lib/elasticated/client.rb +27 -3
  27. data/lib/elasticated/conditions/custom_condition.rb +3 -3
  28. data/lib/elasticated/conditions/range_condition.rb +5 -2
  29. data/lib/elasticated/conditions/script_condition.rb +3 -3
  30. data/lib/elasticated/conditions/standard_condition.rb +4 -5
  31. data/lib/elasticated/conditions/term_condition.rb +22 -0
  32. data/lib/elasticated/conditions/terms_condition.rb +2 -2
  33. data/lib/elasticated/conditions_builder.rb +19 -4
  34. data/lib/elasticated/delimiters/date_field_delimiter.rb +21 -12
  35. data/lib/elasticated/delimiters/standard_field_delimiter.rb +18 -2
  36. data/lib/elasticated/delimiters/term_field_delimiter.rb +6 -5
  37. data/lib/elasticated/document.rb +20 -1
  38. data/lib/elasticated/enum.rb +17 -0
  39. data/lib/elasticated/index_selector.rb +26 -25
  40. data/lib/elasticated/mapping.rb +2 -4
  41. data/lib/elasticated/mapping/builder.rb +3 -2
  42. data/lib/elasticated/mapping/fields_builder.rb +13 -9
  43. data/lib/elasticated/mapping/object_builder.rb +38 -4
  44. data/lib/elasticated/mapping/type_builder.rb +3 -5
  45. data/lib/elasticated/mixins/block_evaluation.rb +17 -0
  46. data/lib/elasticated/mixins/clonable.rb +60 -0
  47. data/lib/elasticated/mixins/configurable.rb +22 -0
  48. data/lib/elasticated/mixins/inspectionable.rb +16 -0
  49. data/lib/elasticated/partitioned_repository.rb +24 -18
  50. data/lib/elasticated/query.rb +27 -21
  51. data/lib/elasticated/query_aggregations.rb +5 -7
  52. data/lib/elasticated/query_conditions.rb +6 -3
  53. data/lib/elasticated/quick.rb +7 -0
  54. data/lib/elasticated/repository.rb +184 -40
  55. data/lib/elasticated/repository/intelligent_search.rb +3 -3
  56. data/lib/elasticated/repository/normal_search.rb +2 -2
  57. data/lib/elasticated/repository/resumable_search.rb +5 -5
  58. data/lib/elasticated/repository/scan_scroll_search.rb +4 -4
  59. data/lib/elasticated/repository/scroll_search.rb +3 -3
  60. data/lib/elasticated/repository/search.rb +7 -0
  61. data/lib/elasticated/repository/single_page_search.rb +1 -1
  62. data/lib/elasticated/results.rb +14 -0
  63. data/lib/version.rb +18 -25
  64. data/spec/aggregation_spec.rb +95 -16
  65. data/spec/bulk_request_spec.rb +158 -0
  66. data/spec/date_field_delimiter_spec.rb +50 -6
  67. data/spec/document_spec.rb +1 -5
  68. data/spec/integration_spec.rb +7 -7
  69. data/spec/mapping_spec.rb +128 -8
  70. data/spec/partitioned_repository_spec.rb +218 -0
  71. data/spec/query_conditions_spec.rb +98 -45
  72. data/spec/query_spec.rb +21 -28
  73. data/spec/repository_spec.rb +245 -0
  74. data/spec/results_spec.rb +0 -4
  75. data/spec/sample_responses/elasticsearch_bulk_response_1.json +35 -0
  76. data/spec/sample_responses/elasticsearch_bulk_response_2.json +20 -0
  77. data/spec/sample_responses/elasticsearch_count_1.json +8 -0
  78. data/spec/sample_responses/elasticsearch_count_2.json +8 -0
  79. data/spec/sample_responses/elasticsearch_get_response_1.json +10 -0
  80. data/spec/sample_responses/elasticsearch_get_response_2.json +6 -0
  81. data/spec/{elasticsearch_hit_1.json → sample_responses/elasticsearch_hit_1.json} +0 -0
  82. data/spec/sample_responses/elasticsearch_mget_response_1.json +25 -0
  83. data/spec/{elasticsearch_response_1.json → sample_responses/elasticsearch_response_1.json} +0 -0
  84. data/spec/{elasticsearch_response_2.json → sample_responses/elasticsearch_response_2.json} +0 -0
  85. data/spec/{elasticsearch_top_hits_response.json → sample_responses/elasticsearch_top_hits_response.json} +0 -0
  86. data/spec/spec_helper.rb +47 -0
  87. data/spec/spec_helper/fake_index_selector.rb +27 -0
  88. data/spec/term_field_delimiter_spec.rb +8 -8
  89. metadata +80 -26
  90. data/lib/elasticated/block_evaluation.rb +0 -15
  91. data/lib/elasticated/clonable.rb +0 -58
  92. data/lib/elasticated/configurable.rb +0 -20
  93. data/lib/elasticated/date_delimiter_factory.rb +0 -123
  94. data/lib/elasticated/delimiter_visitor.rb +0 -53
  95. data/lib/elasticated/inspectionable.rb +0 -9
  96. data/lib/elasticated/strategy_params_for_query_service.rb +0 -14
  97. data/lib/elasticated/term_delimiter_factory.rb +0 -73
  98. data/spec/delimiter_factory_spec.rb +0 -399
  99. 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.equal :field, :value
17
- expected_result = { terms: { field: [:value] } }
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.equal :field, :value, execution: :bool, _cache: false
23
- expected_result = { terms: { field: [:value], execution: :bool, _cache: false } }
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, :value
29
- expected_result = { bool: { must_not: [ { terms: { field: [:value] } } ] } }
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.equal :field, :value
137
+ n.term :field, :value
126
138
  end
127
- expected_result = { nested: { path: :hash, filter: { terms: { field: [:value] } } } }
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.equal :field, :value
145
+ n.term :field, :value
134
146
  end
135
- expected_result = { nested: { path: :hash, _cache: true, filter: { terms: { field: [:value] } } } }
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.equal :field, :value
160
- expected_result = { bool: { must: [ { exists: { field: :field } }, { terms: { field: [:value] } } ] } }
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.equal :field, :value
160
+ qc.term :field, :value
167
161
  qc.cache
168
- expected_result = { bool: { must: [ { exists: { field: :field } }, { terms: { field: [:value] } } ], _cache: true } }
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: [ {terms: { field_one: [:value_one] } } ],
179
- must_not: [ { terms: { field_two: [:value_two] } } ],
180
- should: [ { terms: { field_three: [:value_three] } } ],
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
- { terms: { age: [19] } }
187
+ { term: { age: 19 } }
194
188
  ],
195
189
  should: [
196
- { terms: { name: ['Pablo'] } },
197
- { terms: { name: ['Santiago'] } }
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
- { terms: { first_name: ['Pablo'] } },
217
- { terms: { last_name: ['Fernandez'] } },
210
+ { term: { first_name: 'Pablo' } },
211
+ { term: { last_name: 'Fernandez' } },
218
212
  {
219
213
  bool: {
220
214
  must: [
221
- { terms: { age: [24] } },
222
- { terms: { country: ['Argentina'] } }
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: [ {terms: { field_one: [:value_one] } } ],
246
- must_not: [ { terms: { field_two: [:value_two] } } ],
247
- should: [ { terms: { field_three: [:value_three] } } ]
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
- group :entry_type, size: 5 do
227
- group :entry_name, compact: true
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
- { terms: { last_name: ['Fernandez'] } }
233
+ { term: { last_name: 'Fernandez' } },
234
+ { terms: { age: [23, 24] } }
243
235
  ],
244
236
  should: [
245
- { terms: { first_name: ['Pablo'] } },
237
+ { term: { first_name: 'Pablo' } },
246
238
  {
247
239
  bool: {
248
240
  must: [
249
- { terms: { first_name: ['Tomas'] } },
250
- { terms: { second_name: ['Agustin'] } }
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
- { terms: { city: ['CABA'] } }
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