elasticated 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/Gemfile +4 -0
  4. data/README.md +3 -0
  5. data/Rakefile +6 -0
  6. data/elasticated.gemspec +29 -0
  7. data/lib/elasticated.rb +102 -0
  8. data/lib/elasticated/aggregation.rb +36 -0
  9. data/lib/elasticated/aggregations/cardinality_aggregation.rb +15 -0
  10. data/lib/elasticated/aggregations/count_aggregation.rb +15 -0
  11. data/lib/elasticated/aggregations/count_distinct_aggregation.rb +15 -0
  12. data/lib/elasticated/aggregations/count_filtered_aggregation.rb +29 -0
  13. data/lib/elasticated/aggregations/custom_aggregation.rb +25 -0
  14. data/lib/elasticated/aggregations/date_histogram_aggregation.rb +35 -0
  15. data/lib/elasticated/aggregations/filter_aggregation.rb +33 -0
  16. data/lib/elasticated/aggregations/filter_aggregation_evaluator.rb +22 -0
  17. data/lib/elasticated/aggregations/group_aggregation.rb +29 -0
  18. data/lib/elasticated/aggregations/histogram_aggregation.rb +34 -0
  19. data/lib/elasticated/aggregations/nested_aggregation.rb +30 -0
  20. data/lib/elasticated/aggregations/range_aggregation.rb +35 -0
  21. data/lib/elasticated/aggregations/range_aggregation_evaluator.rb +22 -0
  22. data/lib/elasticated/aggregations/ranges_builder.rb +35 -0
  23. data/lib/elasticated/aggregations/single_value_aggregation.rb +47 -0
  24. data/lib/elasticated/aggregations/subaggregated.rb +27 -0
  25. data/lib/elasticated/aggregations/sum_distinct_aggregation.rb +20 -0
  26. data/lib/elasticated/aggregations/terms_aggregation.rb +63 -0
  27. data/lib/elasticated/aggregations/top_hits_aggregation.rb +25 -0
  28. data/lib/elasticated/block_evaluation.rb +15 -0
  29. data/lib/elasticated/boolean_clause.rb +43 -0
  30. data/lib/elasticated/client.rb +84 -0
  31. data/lib/elasticated/clonable.rb +58 -0
  32. data/lib/elasticated/conditions/custom_condition.rb +19 -0
  33. data/lib/elasticated/conditions/exists_condition.rb +11 -0
  34. data/lib/elasticated/conditions/missing_condition.rb +11 -0
  35. data/lib/elasticated/conditions/nested_condition.rb +19 -0
  36. data/lib/elasticated/conditions/range_condition.rb +27 -0
  37. data/lib/elasticated/conditions/script_condition.rb +22 -0
  38. data/lib/elasticated/conditions/standard_condition.rb +26 -0
  39. data/lib/elasticated/conditions/terms_condition.rb +22 -0
  40. data/lib/elasticated/conditions/wildcard_condition.rb +18 -0
  41. data/lib/elasticated/conditions_builder.rb +75 -0
  42. data/lib/elasticated/configurable.rb +9 -0
  43. data/lib/elasticated/configuration.rb +9 -0
  44. data/lib/elasticated/default_logger.rb +27 -0
  45. data/lib/elasticated/delimiters/date_field_delimiter.rb +33 -0
  46. data/lib/elasticated/delimiters/standard_field_delimiter.rb +33 -0
  47. data/lib/elasticated/delimiters/term_field_delimiter.rb +24 -0
  48. data/lib/elasticated/document.rb +46 -0
  49. data/lib/elasticated/helpers.rb +28 -0
  50. data/lib/elasticated/index_selector.rb +44 -0
  51. data/lib/elasticated/inspectionable.rb +9 -0
  52. data/lib/elasticated/mapping.rb +19 -0
  53. data/lib/elasticated/mapping/builder.rb +36 -0
  54. data/lib/elasticated/mapping/fields_builder.rb +148 -0
  55. data/lib/elasticated/mapping/nested_builder.rb +15 -0
  56. data/lib/elasticated/mapping/object_builder.rb +15 -0
  57. data/lib/elasticated/mapping/partial.rb +11 -0
  58. data/lib/elasticated/mapping/type_builder.rb +14 -0
  59. data/lib/elasticated/partitioned_repository.rb +27 -0
  60. data/lib/elasticated/query.rb +159 -0
  61. data/lib/elasticated/query_aggregations.rb +71 -0
  62. data/lib/elasticated/query_conditions.rb +89 -0
  63. data/lib/elasticated/repositories/monthly_partitioned_repository.rb +96 -0
  64. data/lib/elasticated/repository.rb +139 -0
  65. data/lib/elasticated/results.rb +43 -0
  66. data/lib/version.rb +92 -0
  67. data/spec/aggregation_spec.rb +587 -0
  68. data/spec/date_field_delimiter_spec.rb +67 -0
  69. data/spec/document_spec.rb +44 -0
  70. data/spec/elasticsearch_hit_1.json +14 -0
  71. data/spec/elasticsearch_response_1.json +29 -0
  72. data/spec/elasticsearch_response_2.json +44 -0
  73. data/spec/elasticsearch_top_hits_response.json +20 -0
  74. data/spec/integration_spec.rb +184 -0
  75. data/spec/mapping_spec.rb +219 -0
  76. data/spec/monthly_partitioned_repository_spec.rb +99 -0
  77. data/spec/query_aggregations_spec.rb +44 -0
  78. data/spec/query_conditions_spec.rb +314 -0
  79. data/spec/query_spec.rb +265 -0
  80. data/spec/results_spec.rb +69 -0
  81. data/spec/spec_helper.rb +2 -0
  82. data/spec/term_field_delimiter_spec.rb +39 -0
  83. metadata +225 -0
@@ -0,0 +1,587 @@
1
+ require_relative 'spec_helper'
2
+
3
+ module Elasticated
4
+
5
+ describe MaxAggregation do
6
+
7
+ it "should build a max aggregation over a field" do
8
+ agg = MaxAggregation.new :numeric_field
9
+ expected_result = { max: { field: :numeric_field } }
10
+ expect(agg.build).to eq expected_result
11
+ end
12
+
13
+ it "should build a max aggregation over a field with custom params" do
14
+ agg = MaxAggregation.new :numeric_field, script: 'your_script'
15
+ expected_result = { max: { field: :numeric_field, script: 'your_script' } }
16
+ expect(agg.build).to eq expected_result
17
+ end
18
+
19
+ it "should map a single value aggregated response" do
20
+ agg = MaxAggregation.new :numeric_field
21
+ response = { 'value' => 54 }
22
+ expect(agg.parse(response)).to eq 54
23
+ end
24
+
25
+ end
26
+
27
+ # sum, min, and avg aggregations are the same as max aggregation
28
+
29
+ describe CardinalityAggregation do
30
+
31
+ it "should build a cardinality aggregation over a field" do
32
+ agg = CardinalityAggregation.new :some_field
33
+ expected_result = { cardinality: { field: :some_field } }
34
+ expect(agg.build).to eq expected_result
35
+ end
36
+
37
+ it "should build a cardinality aggregation over a field with custom params" do
38
+ agg = CardinalityAggregation.new :some_field, precision_threshold: 100
39
+ expected_result = { cardinality: { field: :some_field, precision_threshold: 100 } }
40
+ expect(agg.build).to eq expected_result
41
+ end
42
+
43
+ it "should map a single value aggregated response" do
44
+ agg = CardinalityAggregation.new :some_field
45
+ response = { 'value' => 54 }
46
+ expect(agg.parse(response)).to eq 54
47
+ end
48
+ end
49
+
50
+ describe CountFilteredAggregation do
51
+
52
+ it "should build a filter aggregation over a field" do
53
+ agg = CountFilteredAggregation.new :filter_name do |f|
54
+ f.must{ custom my_filter: {} }
55
+ end
56
+ expected_result = { filter: { my_filter: {} } }
57
+ expect(agg.build).to eq expected_result
58
+ end
59
+
60
+ it "should map a 'count filtered' aggregation response" do
61
+ agg = CountFilteredAggregation.new :filter_by_field do |f|
62
+ f.equal :field, :value
63
+ end
64
+ response = { 'doc_count' => 678 }
65
+ expect(agg.parse(response)).to eq 678
66
+ end
67
+
68
+ end
69
+
70
+ describe GroupAggregation do
71
+
72
+ it "should build a terms aggregation over a field" do
73
+ agg = GroupAggregation.new :user
74
+ expected_result = { terms: { field: :user, size: 0 } }
75
+ expect(agg.build).to eq expected_result
76
+ end
77
+
78
+ it "should build a terms aggregation over a field with limited size" do
79
+ agg = GroupAggregation.new :user, size: 5
80
+ expected_result = { terms: { field: :user, size: 5 } }
81
+ expect(agg.build).to eq expected_result
82
+ end
83
+
84
+ it "should build a terms aggregation over a field with some sorting" do
85
+ agg = GroupAggregation.new :user, order: :age
86
+ expected_result = { terms: { field: :user, size: 0, order: { age: :desc } } }
87
+ expect(agg.build).to eq expected_result
88
+ end
89
+
90
+ it "should build a terms aggregation over a field with some sorting and method" do
91
+ agg = GroupAggregation.new :user, order: :age, order_method: :asc
92
+ expected_result = { terms: { field: :user, size: 0, order: { age: :asc } } }
93
+ expect(agg.build).to eq expected_result
94
+ end
95
+
96
+ it "should build a terms aggregation over a field with some sorting hash" do
97
+ agg = GroupAggregation.new :user, order: { age: :desc }
98
+ expected_result = { terms: { field: :user, size: 0, order: { age: :desc } } }
99
+ expect(agg.build).to eq expected_result
100
+ end
101
+
102
+ it "should build a terms aggregation over a field with some sorting string" do
103
+ agg = GroupAggregation.new :user, order: 'some_field:asc'
104
+ expected_result = { terms: { field: :user, size: 0, order: { 'some_field' => 'asc' } } }
105
+ expect(agg.build).to eq expected_result
106
+ end
107
+
108
+ it "should build a terms aggregation over a field with a multiple sorting hash" do
109
+ agg = GroupAggregation.new :user, order: { age: :asc, name: :desc }
110
+ expected_result = { terms: { field: :user, size: 0, order: [ { age: :asc }, { name: :desc } ] } }
111
+ expect(agg.build).to eq expected_result
112
+ end
113
+
114
+ it "should build a terms aggregation over a field with multiple sorting strings" do
115
+ agg = GroupAggregation.new :user, order: ['some_field:asc', 'name:desc']
116
+ expected_result = { terms: { field: :user, size: 0, order: [ { 'some_field' => 'asc' }, { 'name' => 'desc' } ] } }
117
+ expect(agg.build).to eq expected_result
118
+ end
119
+
120
+ it "should build a terms aggregation over a field with multiple partial sorting strings" do
121
+ agg = GroupAggregation.new :user, order: ['some_field', 'name:asc']
122
+ expected_result = { terms: { field: :user, size: 0, order: [ { 'some_field' => :desc }, { 'name' => 'asc' } ] } }
123
+ expect(agg.build).to eq expected_result
124
+ end
125
+
126
+ it "should build a terms aggregation over a field with custom params" do
127
+ agg = GroupAggregation.new :user, order: :age, order_method: :asc, size: 15, script: 'your_script'
128
+ expected_result = { terms: { field: :user, size: 15, order: { age: :asc }, script: 'your_script' } }
129
+ expect(agg.build).to eq expected_result
130
+ end
131
+
132
+ it "should build a terms aggregation over a field with subaggregations" do
133
+ agg = GroupAggregation.new :user do |user|
134
+ user.max :age
135
+ user.sum :childs
136
+ end
137
+ expected_result = {
138
+ terms: { field: :user, size: 0 },
139
+ aggs: {
140
+ max_age: { max: { field: :age } },
141
+ sum_childs: { sum: { field: :childs } }
142
+ }
143
+ }
144
+ expect(agg.build).to eq expected_result
145
+ end
146
+
147
+ it "should map a group aggregation response" do
148
+ agg = GroupAggregation.new :field
149
+ response = { 'buckets' => [
150
+ { 'key' => 'value1', 'doc_count' => 'count1' },
151
+ { 'key' => 'value2', 'doc_count' => 'count2' },
152
+ { 'key' => 'value3', 'doc_count' => 'count3' }
153
+ ] }
154
+ expect(agg.parse(response)).to eq({
155
+ 'value1' => { 'count' => 'count1' },
156
+ 'value2' => { 'count' => 'count2' },
157
+ 'value3' => { 'count' => 'count3' }
158
+ })
159
+ end
160
+
161
+ end
162
+
163
+ describe CountAggregation do
164
+
165
+ it "should build a terms aggregation over a field" do
166
+ agg = CountAggregation.new :user
167
+ expected_result = { terms: { field: :user, size: 0 } }
168
+ expect(agg.build).to eq expected_result
169
+ end
170
+
171
+ it "should build a terms aggregation over a field with custom params" do
172
+ agg = CountAggregation.new :user, script: 'your_script'
173
+ expected_result = { terms: { field: :user, size: 0, script: 'your_script' } }
174
+ expect(agg.build).to eq expected_result
175
+ end
176
+
177
+ it "should map a 'count' aggregation response" do
178
+ agg = CountAggregation.new :field
179
+ response = { 'buckets' => [
180
+ { 'key' => 'value1', 'doc_count' => 'count1' },
181
+ { 'key' => 'value2', 'doc_count' => 'count2' },
182
+ { 'key' => 'value3', 'doc_count' => 'count3' }
183
+ ] }
184
+ expect(agg.parse(response)).to eq({
185
+ 'value1' => 'count1',
186
+ 'value2' => 'count2',
187
+ 'value3' => 'count3'
188
+ })
189
+ end
190
+
191
+ end
192
+
193
+ describe CountDistinctAggregation do
194
+
195
+ it "should build a terms aggregation over a field" do
196
+ agg = CountDistinctAggregation.new :user
197
+ expected_result = { value_count: { field: :user } }
198
+ expect(agg.build).to eq expected_result
199
+ end
200
+
201
+ end
202
+
203
+ describe HistogramAggregation do
204
+
205
+ it "should build a histogram aggregation" do
206
+ agg = HistogramAggregation.new :age, 7
207
+ expected_result = { histogram: { field: :age, interval: 7 } }
208
+ expect(agg.build).to eq expected_result
209
+ end
210
+
211
+ it "should build a histogram aggregation with custom params" do
212
+ agg = HistogramAggregation.new :age, 7, script: 'your_script'
213
+ expected_result = { histogram: { field: :age, interval: 7, script: 'your_script' } }
214
+ expect(agg.build).to eq expected_result
215
+ end
216
+
217
+ it "should build a histogram aggregation with subaggregations" do
218
+ agg = HistogramAggregation.new :age, 7 do |user|
219
+ user.max :numeric_field
220
+ user.sum :childs
221
+ end
222
+ expected_result = {
223
+ histogram: { field: :age, interval: 7 },
224
+ aggs: {
225
+ max_numeric_field: { max: { field: :numeric_field } },
226
+ sum_childs: { sum: { field: :childs } }
227
+ }
228
+ }
229
+ expect(agg.build).to eq expected_result
230
+ end
231
+
232
+ end
233
+
234
+ describe DateHistogramAggregation do
235
+
236
+ it "should build a date histogram aggregation" do
237
+ agg = DateHistogramAggregation.new :date
238
+ expected_result = { date_histogram: { field: :date, interval: 'day', format: 'yyyy-MM-dd' } }
239
+ expect(agg.build).to eq expected_result
240
+ end
241
+
242
+ it "should build a date histogram aggregation with custom interval" do
243
+ agg = DateHistogramAggregation.new :date, interval: '7d'
244
+ expected_result = { date_histogram: { field: :date, interval: '7d', format: 'yyyy-MM-dd' } }
245
+ expect(agg.build).to eq expected_result
246
+ end
247
+
248
+ it "should build a date histogram aggregation with custom format" do
249
+ agg = DateHistogramAggregation.new :date, interval: '7d', format: 'your_format'
250
+ expected_result = { date_histogram: { field: :date, interval: '7d', format: 'your_format' } }
251
+ expect(agg.build).to eq expected_result
252
+ end
253
+
254
+ it "should build a date histogram aggregation with custom params" do
255
+ agg = DateHistogramAggregation.new :date, script: 'your_script'
256
+ expected_result = { date_histogram: { field: :date, interval: 'day', format: 'yyyy-MM-dd', script: 'your_script' } }
257
+ expect(agg.build).to eq expected_result
258
+ end
259
+
260
+ it "should build a date histogram aggregation with subaggregations" do
261
+ agg = DateHistogramAggregation.new :date do |docs|
262
+ docs.max :numeric_field
263
+ docs.sum :childs
264
+ end
265
+ expected_result = {
266
+ date_histogram: { field: :date, interval: 'day', format: 'yyyy-MM-dd' },
267
+ aggs: {
268
+ max_numeric_field: { max: { field: :numeric_field } },
269
+ sum_childs: { sum: { field: :childs } }
270
+ }
271
+ }
272
+ expect(agg.build).to eq expected_result
273
+ end
274
+
275
+ it "should map a 'date histogram' aggregation response" do
276
+ agg = DateHistogramAggregation.new :field
277
+ response = {'buckets' => [
278
+ { 'key_as_string' => '2014-01-01', 'doc_count' => 'count1' },
279
+ { 'key_as_string' => '2014-01-02', 'doc_count' => 'count2' },
280
+ { 'key_as_string' => '2014-01-03', 'doc_count' => 'count3' }
281
+ ] }
282
+ expect(agg.parse(response)).to eq({
283
+ '2014-01-01' => { 'count' => 'count1' },
284
+ '2014-01-02' => { 'count' => 'count2' },
285
+ '2014-01-03' => { 'count' => 'count3' }
286
+ })
287
+ end
288
+
289
+ end
290
+
291
+ describe FilterAggregation do
292
+
293
+ it "should build a filter aggregation" do
294
+ agg = FilterAggregation.new :some_name do |f|
295
+ f.conditions do |c|
296
+ c.must{ custom my_filter: {} }
297
+ end
298
+ end
299
+ expected_result = { filter: { my_filter: {} } }
300
+ expect(agg.build).to eq expected_result
301
+ end
302
+
303
+ it "should build a filter aggregation with subaggregations" do
304
+ agg = FilterAggregation.new :some_name do |f|
305
+ f.conditions do |c|
306
+ c.must{ custom my_filter: {} }
307
+ end
308
+ f.max :age
309
+ f.sum :numeric_field
310
+ end
311
+ expected_result = {
312
+ filter: { my_filter: {} },
313
+ aggs: {
314
+ max_age: { max: { field: :age } },
315
+ sum_numeric_field: { sum: { field: :numeric_field } }
316
+ }
317
+ }
318
+ expect(agg.build).to eq expected_result
319
+ end
320
+
321
+ end
322
+
323
+ describe NestedAggregation do
324
+
325
+ it "should build a nested aggregation" do
326
+ agg = NestedAggregation.new 'some.path'
327
+ expected_result = { nested: { path: 'some.path' } }
328
+ expect(agg.build).to eq expected_result
329
+ end
330
+
331
+ it "should build a nested aggregation with an alias" do
332
+ agg = NestedAggregation.new 'some.path', as: :some_alias
333
+ expected_result = { nested: { path: 'some.path' } }
334
+ expect(agg.build).to eq expected_result
335
+ end
336
+
337
+ it "should build a nested aggregation" do
338
+ agg = NestedAggregation.new 'some.path' do |n|
339
+ n.max :age
340
+ n.sum :numeric_field
341
+ end
342
+ expected_result = {
343
+ nested: { path: 'some.path' },
344
+ aggs: {
345
+ max_age: { max: { field: :age } },
346
+ sum_numeric_field: { sum: { field: :numeric_field } }
347
+ }
348
+ }
349
+ expect(agg.build).to eq expected_result
350
+ end
351
+
352
+ it "should map a 'nested' response" do
353
+ agg = NestedAggregation.new 'my_path' do |n|
354
+ n.group :user
355
+ end
356
+ response = {
357
+ 'doc_count' => 5,
358
+ 'group_by_user' => {
359
+ 'buckets' => [ { 'key' => 'user1', 'doc_count' => 2 } ]
360
+ }
361
+ }
362
+ expect(agg.parse(response)).to eq({
363
+ 'count' => 5,
364
+ 'group_by_user' => { 'user1' => { 'count' => 2 } }
365
+ })
366
+ end
367
+
368
+ end
369
+
370
+ describe RangeAggregation do
371
+
372
+ it "should build a range aggregation" do
373
+ agg = RangeAggregation.new :numeric_field do |f|
374
+ f.ranges do |c|
375
+ c.less_equal 15
376
+ c.between 15, 20
377
+ c.greater_equal 20
378
+ end
379
+ end
380
+ expected_result = {
381
+ range: {
382
+ field: :numeric_field,
383
+ keyed: true,
384
+ ranges: [
385
+ { key: 'less_equal_15', to: 15 },
386
+ { key: 'between_15_and_20', from: 15, to: 20 },
387
+ { key: 'greater_equal_20', from: 20 }
388
+ ]
389
+ }
390
+ }
391
+ expect(agg.build).to eq expected_result
392
+ end
393
+
394
+ it "should build a range aggregation with extra params" do
395
+ agg = RangeAggregation.new :numeric_field, script: 'your_script' do |f|
396
+ f.ranges do |c|
397
+ c.less_equal 15
398
+ c.between 15, 20
399
+ c.greater_equal 20
400
+ end
401
+ end
402
+ expected_result = {
403
+ range: {
404
+ field: :numeric_field,
405
+ keyed: true,
406
+ script: 'your_script',
407
+ ranges: [
408
+ { key: 'less_equal_15', to: 15 },
409
+ { key: 'between_15_and_20', from: 15, to: 20 },
410
+ { key: 'greater_equal_20', from: 20 }
411
+ ]
412
+ }
413
+ }
414
+ expect(agg.build).to eq expected_result
415
+ end
416
+
417
+ it "should build a range aggregation with subaggregations" do
418
+ agg = RangeAggregation.new :numeric_field do |f|
419
+ f.ranges do |c|
420
+ c.less_equal 15
421
+ c.between 15, 20
422
+ c.greater_equal 20
423
+ end
424
+ f.max :age
425
+ f.sum :numeric_field
426
+ end
427
+ expected_result = {
428
+ range: {
429
+ field: :numeric_field,
430
+ keyed: true,
431
+ ranges: [
432
+ { key: 'less_equal_15', to: 15 },
433
+ { key: 'between_15_and_20', from: 15, to: 20 },
434
+ { key: 'greater_equal_20', from: 20 }
435
+ ]
436
+ },
437
+ aggs: {
438
+ max_age: { max: { field: :age } },
439
+ sum_numeric_field: { sum: { field: :numeric_field } }
440
+ }
441
+ }
442
+ expect(agg.build).to eq expected_result
443
+ end
444
+
445
+ it "should map a 'range' response" do
446
+ agg = RangeAggregation.new :a_field do |a|
447
+ a.ranges do |r|
448
+ r.greater_equal :max_value, 'high_values'
449
+ r.less_equal :min_value
450
+ r.between :min_value, :max_value
451
+ end
452
+ end
453
+ response = {
454
+ 'buckets' => {
455
+ 'high_values' => {
456
+ 'from' => 'max_value',
457
+ 'doc_count' => 5
458
+ },
459
+ 'less_equal_min_value' => {
460
+ 'to' => 'min_value',
461
+ 'doc_count' => 3
462
+ },
463
+ 'between_min_value_and_max_value' => {
464
+ 'from' => 'min_value',
465
+ 'to' => 'max_value',
466
+ 'doc_count' => 9
467
+ }
468
+ }
469
+ }
470
+ expect(agg.parse(response)).to eq({
471
+ 'high_values' => { 'count' => 5 },
472
+ 'less_equal_min_value' => { 'count' => 3 },
473
+ 'between_min_value_and_max_value' => { 'count' => 9 }
474
+ })
475
+ end
476
+
477
+ end
478
+
479
+ describe SumDistinctAggregation do
480
+
481
+ it "should build a terms aggregation over a field" do
482
+ agg = SumDistinctAggregation.new :user, :sum, :money
483
+ expected_result = {
484
+ terms: { field: :user, size: 0 },
485
+ aggs: {
486
+ sum_money: {
487
+ sum: { field: :money }
488
+ }
489
+ }
490
+ }
491
+ expect(agg.build).to eq expected_result
492
+ end
493
+
494
+ it "should build a terms aggregation over a field with custom params" do
495
+ agg = SumDistinctAggregation.new :user, :sum, :money, script: 'your_script'
496
+ expected_result = {
497
+ terms: { field: :user, size: 0, script: 'your_script' },
498
+ aggs: {
499
+ sum_money: {
500
+ sum: { field: :money }
501
+ }
502
+ }
503
+ }
504
+ expect(agg.build).to eq expected_result
505
+ end
506
+
507
+ it "should map a 'sum distinct' response" do
508
+ agg = SumDistinctAggregation.new :field, :max, :number, size: 5
509
+ response = { 'buckets' => [
510
+ { 'key' => 'value1', 'doc_count' => 'count1', 'max_number' => { 'value' => 12 } },
511
+ { 'key' => 'value2', 'doc_count' => 'count2', 'max_number' => { 'value' => 55 } },
512
+ { 'key' => 'value3', 'doc_count' => 'count3', 'max_number' => { 'value' => 32 } }
513
+ ] }
514
+ expect(agg.parse(response)).to eq(12 + 55 + 32)
515
+ end
516
+
517
+ end
518
+
519
+ describe TopHitsAggregation do
520
+
521
+ def open_response(name)
522
+ JSON.parse File.read "spec/#{name}.json"
523
+ end
524
+
525
+ it "should build a 'top hits' aggregation" do
526
+ agg = TopHitsAggregation.new :some_name do |q|
527
+ q.size 5
528
+ q.sort :username, :desc
529
+ q.source :username
530
+ end
531
+ expected_result = {
532
+ top_hits: {
533
+ size: 5,
534
+ sort: [{ username: { order: :desc } }],
535
+ _source: [:username]
536
+ }
537
+ }
538
+ expect(agg.build).to eq expected_result
539
+ end
540
+
541
+ it "should map a 'top hits' response" do
542
+ agg = TopHitsAggregation.new :some_name
543
+ response = open_response 'elasticsearch_top_hits_response'
544
+ result = agg.parse response
545
+ # expect(result.total).to eq 25365
546
+ # expect(result.max_score).to eq 1
547
+ # expect(result.hits.count).to eq 1
548
+ # document = result.hits.first
549
+ expect(result.count).to eq 1
550
+ document = result.first
551
+ expect(document).to be_a Document
552
+ expect(document.index).to eq 'stack'
553
+ expect(document.type).to eq 'question'
554
+ expect(document.source['title']).to eq 'Windows port opening'
555
+ end
556
+
557
+ end
558
+
559
+ describe CustomAggregation do
560
+
561
+ it "should build a custom aggregation" do
562
+ agg = CustomAggregation.new :my_agg do
563
+ { custom_aggregation: { field: :some_field } }
564
+ end
565
+ expected_result = {
566
+ custom_aggregation: {
567
+ field: :some_field
568
+ }
569
+ }
570
+ expect(agg.build).to eq expected_result
571
+ end
572
+
573
+ it "should map a custom aggregation response" do
574
+ agg = CustomAggregation.new :my_agg do
575
+ { custom_aggregation: { field: :some_field } }
576
+ end
577
+ response = { 'buckets' => [
578
+ { 'key' => 'value1', 'doc_count' => 'count1', 'max_number' => { 'value' => 12 } },
579
+ { 'key' => 'value2', 'doc_count' => 'count2', 'max_number' => { 'value' => 55 } },
580
+ { 'key' => 'value3', 'doc_count' => 'count3', 'max_number' => { 'value' => 32 } }
581
+ ] }
582
+ expect(agg.parse(response)).to eq response
583
+ end
584
+
585
+ end
586
+
587
+ end