elasticated 1.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 +7 -0
- data/.gitignore +35 -0
- data/Gemfile +4 -0
- data/README.md +3 -0
- data/Rakefile +6 -0
- data/elasticated.gemspec +29 -0
- data/lib/elasticated.rb +102 -0
- data/lib/elasticated/aggregation.rb +36 -0
- data/lib/elasticated/aggregations/cardinality_aggregation.rb +15 -0
- data/lib/elasticated/aggregations/count_aggregation.rb +15 -0
- data/lib/elasticated/aggregations/count_distinct_aggregation.rb +15 -0
- data/lib/elasticated/aggregations/count_filtered_aggregation.rb +29 -0
- data/lib/elasticated/aggregations/custom_aggregation.rb +25 -0
- data/lib/elasticated/aggregations/date_histogram_aggregation.rb +35 -0
- data/lib/elasticated/aggregations/filter_aggregation.rb +33 -0
- data/lib/elasticated/aggregations/filter_aggregation_evaluator.rb +22 -0
- data/lib/elasticated/aggregations/group_aggregation.rb +29 -0
- data/lib/elasticated/aggregations/histogram_aggregation.rb +34 -0
- data/lib/elasticated/aggregations/nested_aggregation.rb +30 -0
- data/lib/elasticated/aggregations/range_aggregation.rb +35 -0
- data/lib/elasticated/aggregations/range_aggregation_evaluator.rb +22 -0
- data/lib/elasticated/aggregations/ranges_builder.rb +35 -0
- data/lib/elasticated/aggregations/single_value_aggregation.rb +47 -0
- data/lib/elasticated/aggregations/subaggregated.rb +27 -0
- data/lib/elasticated/aggregations/sum_distinct_aggregation.rb +20 -0
- data/lib/elasticated/aggregations/terms_aggregation.rb +63 -0
- data/lib/elasticated/aggregations/top_hits_aggregation.rb +25 -0
- data/lib/elasticated/block_evaluation.rb +15 -0
- data/lib/elasticated/boolean_clause.rb +43 -0
- data/lib/elasticated/client.rb +84 -0
- data/lib/elasticated/clonable.rb +58 -0
- data/lib/elasticated/conditions/custom_condition.rb +19 -0
- data/lib/elasticated/conditions/exists_condition.rb +11 -0
- data/lib/elasticated/conditions/missing_condition.rb +11 -0
- data/lib/elasticated/conditions/nested_condition.rb +19 -0
- data/lib/elasticated/conditions/range_condition.rb +27 -0
- data/lib/elasticated/conditions/script_condition.rb +22 -0
- data/lib/elasticated/conditions/standard_condition.rb +26 -0
- data/lib/elasticated/conditions/terms_condition.rb +22 -0
- data/lib/elasticated/conditions/wildcard_condition.rb +18 -0
- data/lib/elasticated/conditions_builder.rb +75 -0
- data/lib/elasticated/configurable.rb +9 -0
- data/lib/elasticated/configuration.rb +9 -0
- data/lib/elasticated/default_logger.rb +27 -0
- data/lib/elasticated/delimiters/date_field_delimiter.rb +33 -0
- data/lib/elasticated/delimiters/standard_field_delimiter.rb +33 -0
- data/lib/elasticated/delimiters/term_field_delimiter.rb +24 -0
- data/lib/elasticated/document.rb +46 -0
- data/lib/elasticated/helpers.rb +28 -0
- data/lib/elasticated/index_selector.rb +44 -0
- data/lib/elasticated/inspectionable.rb +9 -0
- data/lib/elasticated/mapping.rb +19 -0
- data/lib/elasticated/mapping/builder.rb +36 -0
- data/lib/elasticated/mapping/fields_builder.rb +148 -0
- data/lib/elasticated/mapping/nested_builder.rb +15 -0
- data/lib/elasticated/mapping/object_builder.rb +15 -0
- data/lib/elasticated/mapping/partial.rb +11 -0
- data/lib/elasticated/mapping/type_builder.rb +14 -0
- data/lib/elasticated/partitioned_repository.rb +27 -0
- data/lib/elasticated/query.rb +159 -0
- data/lib/elasticated/query_aggregations.rb +71 -0
- data/lib/elasticated/query_conditions.rb +89 -0
- data/lib/elasticated/repositories/monthly_partitioned_repository.rb +96 -0
- data/lib/elasticated/repository.rb +139 -0
- data/lib/elasticated/results.rb +43 -0
- data/lib/version.rb +92 -0
- data/spec/aggregation_spec.rb +587 -0
- data/spec/date_field_delimiter_spec.rb +67 -0
- data/spec/document_spec.rb +44 -0
- data/spec/elasticsearch_hit_1.json +14 -0
- data/spec/elasticsearch_response_1.json +29 -0
- data/spec/elasticsearch_response_2.json +44 -0
- data/spec/elasticsearch_top_hits_response.json +20 -0
- data/spec/integration_spec.rb +184 -0
- data/spec/mapping_spec.rb +219 -0
- data/spec/monthly_partitioned_repository_spec.rb +99 -0
- data/spec/query_aggregations_spec.rb +44 -0
- data/spec/query_conditions_spec.rb +314 -0
- data/spec/query_spec.rb +265 -0
- data/spec/results_spec.rb +69 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/term_field_delimiter_spec.rb +39 -0
- 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
|