elasticsearch-dsl 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +16 -0
  3. data/LICENSE.txt +10 -19
  4. data/README.md +244 -15
  5. data/Rakefile +212 -0
  6. data/elasticsearch-dsl.gemspec +32 -15
  7. data/lib/elasticsearch-dsl.rb +1 -0
  8. data/lib/elasticsearch/dsl.rb +43 -3
  9. data/lib/elasticsearch/dsl/search.rb +241 -0
  10. data/lib/elasticsearch/dsl/search/aggregation.rb +79 -0
  11. data/lib/elasticsearch/dsl/search/aggregations/avg.rb +25 -0
  12. data/lib/elasticsearch/dsl/search/aggregations/cardinality.rb +32 -0
  13. data/lib/elasticsearch/dsl/search/aggregations/children.rb +39 -0
  14. data/lib/elasticsearch/dsl/search/aggregations/date_histogram.rb +40 -0
  15. data/lib/elasticsearch/dsl/search/aggregations/date_range.rb +34 -0
  16. data/lib/elasticsearch/dsl/search/aggregations/extended_stats.rb +25 -0
  17. data/lib/elasticsearch/dsl/search/aggregations/filter.rb +30 -0
  18. data/lib/elasticsearch/dsl/search/aggregations/filters.rb +35 -0
  19. data/lib/elasticsearch/dsl/search/aggregations/geo_bounds.rb +44 -0
  20. data/lib/elasticsearch/dsl/search/aggregations/geo_distance.rb +39 -0
  21. data/lib/elasticsearch/dsl/search/aggregations/geohash_grid.rb +35 -0
  22. data/lib/elasticsearch/dsl/search/aggregations/global.rb +25 -0
  23. data/lib/elasticsearch/dsl/search/aggregations/histogram.rb +35 -0
  24. data/lib/elasticsearch/dsl/search/aggregations/ip_range.rb +31 -0
  25. data/lib/elasticsearch/dsl/search/aggregations/max.rb +25 -0
  26. data/lib/elasticsearch/dsl/search/aggregations/min.rb +25 -0
  27. data/lib/elasticsearch/dsl/search/aggregations/nested.rb +34 -0
  28. data/lib/elasticsearch/dsl/search/aggregations/percentile_ranks.rb +34 -0
  29. data/lib/elasticsearch/dsl/search/aggregations/percentiles.rb +33 -0
  30. data/lib/elasticsearch/dsl/search/aggregations/range.rb +53 -0
  31. data/lib/elasticsearch/dsl/search/aggregations/reverse_nested.rb +37 -0
  32. data/lib/elasticsearch/dsl/search/aggregations/scripted_metric.rb +39 -0
  33. data/lib/elasticsearch/dsl/search/aggregations/significant_terms.rb +45 -0
  34. data/lib/elasticsearch/dsl/search/aggregations/stats.rb +25 -0
  35. data/lib/elasticsearch/dsl/search/aggregations/sum.rb +25 -0
  36. data/lib/elasticsearch/dsl/search/aggregations/terms.rb +33 -0
  37. data/lib/elasticsearch/dsl/search/aggregations/top_hits.rb +35 -0
  38. data/lib/elasticsearch/dsl/search/aggregations/value_count.rb +25 -0
  39. data/lib/elasticsearch/dsl/search/base_aggregation_component.rb +65 -0
  40. data/lib/elasticsearch/dsl/search/base_component.rb +162 -0
  41. data/lib/elasticsearch/dsl/search/base_compound_filter_component.rb +97 -0
  42. data/lib/elasticsearch/dsl/search/filter.rb +56 -0
  43. data/lib/elasticsearch/dsl/search/filters/and.rb +45 -0
  44. data/lib/elasticsearch/dsl/search/filters/bool.rb +80 -0
  45. data/lib/elasticsearch/dsl/search/filters/exists.rb +32 -0
  46. data/lib/elasticsearch/dsl/search/filters/geo_bounding_box.rb +45 -0
  47. data/lib/elasticsearch/dsl/search/filters/geo_distance.rb +57 -0
  48. data/lib/elasticsearch/dsl/search/filters/geo_distance_range.rb +32 -0
  49. data/lib/elasticsearch/dsl/search/filters/geo_polygon.rb +41 -0
  50. data/lib/elasticsearch/dsl/search/filters/geo_shape.rb +35 -0
  51. data/lib/elasticsearch/dsl/search/filters/geohash_cell.rb +46 -0
  52. data/lib/elasticsearch/dsl/search/filters/has_child.rb +73 -0
  53. data/lib/elasticsearch/dsl/search/filters/has_parent.rb +72 -0
  54. data/lib/elasticsearch/dsl/search/filters/ids.rb +32 -0
  55. data/lib/elasticsearch/dsl/search/filters/indices.rb +77 -0
  56. data/lib/elasticsearch/dsl/search/filters/limit.rb +31 -0
  57. data/lib/elasticsearch/dsl/search/filters/match_all.rb +29 -0
  58. data/lib/elasticsearch/dsl/search/filters/missing.rb +34 -0
  59. data/lib/elasticsearch/dsl/search/filters/nested.rb +58 -0
  60. data/lib/elasticsearch/dsl/search/filters/not.rb +73 -0
  61. data/lib/elasticsearch/dsl/search/filters/or.rb +45 -0
  62. data/lib/elasticsearch/dsl/search/filters/prefix.rb +29 -0
  63. data/lib/elasticsearch/dsl/search/filters/query.rb +54 -0
  64. data/lib/elasticsearch/dsl/search/filters/range.rb +39 -0
  65. data/lib/elasticsearch/dsl/search/filters/regexp.rb +34 -0
  66. data/lib/elasticsearch/dsl/search/filters/script.rb +32 -0
  67. data/lib/elasticsearch/dsl/search/filters/term.rb +32 -0
  68. data/lib/elasticsearch/dsl/search/filters/terms.rb +32 -0
  69. data/lib/elasticsearch/dsl/search/filters/type.rb +34 -0
  70. data/lib/elasticsearch/dsl/search/highlight.rb +92 -0
  71. data/lib/elasticsearch/dsl/search/options.rb +56 -0
  72. data/lib/elasticsearch/dsl/search/queries/bool.rb +75 -0
  73. data/lib/elasticsearch/dsl/search/queries/boosting.rb +33 -0
  74. data/lib/elasticsearch/dsl/search/queries/common.rb +38 -0
  75. data/lib/elasticsearch/dsl/search/queries/constant_score.rb +66 -0
  76. data/lib/elasticsearch/dsl/search/queries/dis_max.rb +35 -0
  77. data/lib/elasticsearch/dsl/search/queries/filtered.rb +77 -0
  78. data/lib/elasticsearch/dsl/search/queries/function_score.rb +102 -0
  79. data/lib/elasticsearch/dsl/search/queries/fuzzy.rb +45 -0
  80. data/lib/elasticsearch/dsl/search/queries/fuzzy_like_this.rb +37 -0
  81. data/lib/elasticsearch/dsl/search/queries/fuzzy_like_this_field.rb +36 -0
  82. data/lib/elasticsearch/dsl/search/queries/geo_shape.rb +31 -0
  83. data/lib/elasticsearch/dsl/search/queries/has_child.rb +57 -0
  84. data/lib/elasticsearch/dsl/search/queries/has_parent.rb +57 -0
  85. data/lib/elasticsearch/dsl/search/queries/ids.rb +28 -0
  86. data/lib/elasticsearch/dsl/search/queries/indices.rb +34 -0
  87. data/lib/elasticsearch/dsl/search/queries/match.rb +34 -0
  88. data/lib/elasticsearch/dsl/search/queries/match_all.rb +27 -0
  89. data/lib/elasticsearch/dsl/search/queries/more_like_this.rb +58 -0
  90. data/lib/elasticsearch/dsl/search/queries/multi_match.rb +35 -0
  91. data/lib/elasticsearch/dsl/search/queries/nested.rb +55 -0
  92. data/lib/elasticsearch/dsl/search/queries/prefix.rb +30 -0
  93. data/lib/elasticsearch/dsl/search/queries/query_string.rb +50 -0
  94. data/lib/elasticsearch/dsl/search/queries/range.rb +47 -0
  95. data/lib/elasticsearch/dsl/search/queries/regexp.rb +31 -0
  96. data/lib/elasticsearch/dsl/search/queries/simple_query_string.rb +38 -0
  97. data/lib/elasticsearch/dsl/search/queries/span_first.rb +28 -0
  98. data/lib/elasticsearch/dsl/search/queries/span_multi.rb +28 -0
  99. data/lib/elasticsearch/dsl/search/queries/span_near.rb +32 -0
  100. data/lib/elasticsearch/dsl/search/queries/span_not.rb +33 -0
  101. data/lib/elasticsearch/dsl/search/queries/span_or.rb +28 -0
  102. data/lib/elasticsearch/dsl/search/queries/span_term.rb +26 -0
  103. data/lib/elasticsearch/dsl/search/queries/template.rb +31 -0
  104. data/lib/elasticsearch/dsl/search/queries/term.rb +27 -0
  105. data/lib/elasticsearch/dsl/search/queries/terms.rb +27 -0
  106. data/lib/elasticsearch/dsl/search/queries/top_children.rb +58 -0
  107. data/lib/elasticsearch/dsl/search/queries/wildcard.rb +30 -0
  108. data/lib/elasticsearch/dsl/search/query.rb +55 -0
  109. data/lib/elasticsearch/dsl/search/sort.rb +50 -0
  110. data/lib/elasticsearch/dsl/search/suggest.rb +28 -0
  111. data/lib/elasticsearch/dsl/utils.rb +25 -0
  112. data/lib/elasticsearch/dsl/version.rb +2 -2
  113. data/test/integration/search_aggregation_children_test.rb +69 -0
  114. data/test/integration/search_aggregation_geo_test.rb +90 -0
  115. data/test/integration/search_aggregation_nested_test.rb +100 -0
  116. data/test/integration/search_aggregations_test.rb +232 -0
  117. data/test/integration/search_filters_test.rb +359 -0
  118. data/test/integration/search_options_test.rb +28 -0
  119. data/test/integration/search_query_test.rb +55 -0
  120. data/test/integration/search_size_from_test.rb +41 -0
  121. data/test/integration/search_sort_test.rb +36 -0
  122. data/test/integration/search_suggest_test.rb +62 -0
  123. data/test/test_helper.rb +62 -0
  124. data/test/unit/aggregations/avg_test.rb +24 -0
  125. data/test/unit/aggregations/cardinality_test.rb +40 -0
  126. data/test/unit/aggregations/children_test.rb +36 -0
  127. data/test/unit/aggregations/date_histogram_test.rb +49 -0
  128. data/test/unit/aggregations/date_range_test.rb +42 -0
  129. data/test/unit/aggregations/extended_stats_test.rb +24 -0
  130. data/test/unit/aggregations/filter_test.rb +31 -0
  131. data/test/unit/aggregations/filters_test.rb +52 -0
  132. data/test/unit/aggregations/geo_bounds_test.rb +37 -0
  133. data/test/unit/aggregations/geo_distance_test.rb +45 -0
  134. data/test/unit/aggregations/geohash_grid_test.rb +40 -0
  135. data/test/unit/aggregations/global_test.rb +20 -0
  136. data/test/unit/aggregations/histogram_test.rb +42 -0
  137. data/test/unit/aggregations/ip_range_test.rb +41 -0
  138. data/test/unit/aggregations/max_test.rb +24 -0
  139. data/test/unit/aggregations/min_test.rb +24 -0
  140. data/test/unit/aggregations/nested_test.rb +48 -0
  141. data/test/unit/aggregations/percentile_ranks_test.rb +41 -0
  142. data/test/unit/aggregations/percentiles_test.rb +40 -0
  143. data/test/unit/aggregations/range_test.rb +48 -0
  144. data/test/unit/aggregations/reverse_nested_test.rb +20 -0
  145. data/test/unit/aggregations/scripted_metric_test.rb +41 -0
  146. data/test/unit/aggregations/significant_terms_test.rb +46 -0
  147. data/test/unit/aggregations/stats_test.rb +24 -0
  148. data/test/unit/aggregations/sum_test.rb +24 -0
  149. data/test/unit/aggregations/terms_test.rb +51 -0
  150. data/test/unit/aggregations/top_hits_test.rb +38 -0
  151. data/test/unit/aggregations/value_count_test.rb +24 -0
  152. data/test/unit/dsl_test.rb +18 -0
  153. data/test/unit/filters/and_test.rb +69 -0
  154. data/test/unit/filters/bool_test.rb +98 -0
  155. data/test/unit/filters/exists_test.rb +36 -0
  156. data/test/unit/filters/geo_bounding_box_test.rb +45 -0
  157. data/test/unit/filters/geo_distance_range_test.rb +51 -0
  158. data/test/unit/filters/geo_distance_test.rb +58 -0
  159. data/test/unit/filters/geo_polygon_test.rb +36 -0
  160. data/test/unit/filters/geo_shape_test.rb +37 -0
  161. data/test/unit/filters/geohash_cell_test.rb +43 -0
  162. data/test/unit/filters/has_child_test.rb +52 -0
  163. data/test/unit/filters/has_parent_test.rb +52 -0
  164. data/test/unit/filters/ids_test.rb +38 -0
  165. data/test/unit/filters/indices_test.rb +52 -0
  166. data/test/unit/filters/limit_test.rb +36 -0
  167. data/test/unit/filters/match_all_test.rb +20 -0
  168. data/test/unit/filters/missing_test.rb +38 -0
  169. data/test/unit/filters/nested_test.rb +40 -0
  170. data/test/unit/filters/not_test.rb +35 -0
  171. data/test/unit/filters/or_test.rb +53 -0
  172. data/test/unit/filters/prefix_test.rb +25 -0
  173. data/test/unit/filters/query_test.rb +33 -0
  174. data/test/unit/filters/range_test.rb +47 -0
  175. data/test/unit/filters/regexp_test.rb +42 -0
  176. data/test/unit/filters/script_test.rb +38 -0
  177. data/test/unit/filters/term_test.rb +27 -0
  178. data/test/unit/filters/terms_test.rb +24 -0
  179. data/test/unit/filters/type_test.rb +36 -0
  180. data/test/unit/queries/bool_test.rb +107 -0
  181. data/test/unit/queries/boosting_test.rb +41 -0
  182. data/test/unit/queries/common_test.rb +42 -0
  183. data/test/unit/queries/constant_score_test.rb +47 -0
  184. data/test/unit/queries/dis_max_test.rb +38 -0
  185. data/test/unit/queries/filtered_test.rb +51 -0
  186. data/test/unit/queries/function_score_test.rb +70 -0
  187. data/test/unit/queries/fuzzy_like_this_field_test.rb +42 -0
  188. data/test/unit/queries/fuzzy_like_this_test.rb +44 -0
  189. data/test/unit/queries/fuzzy_test.rb +40 -0
  190. data/test/unit/queries/geo_shape_test.rb +37 -0
  191. data/test/unit/queries/has_child_test.rb +53 -0
  192. data/test/unit/queries/has_parent_test.rb +39 -0
  193. data/test/unit/queries/ids_test.rb +38 -0
  194. data/test/unit/queries/indices_test.rb +39 -0
  195. data/test/unit/queries/match_all_test.rb +36 -0
  196. data/test/unit/queries/match_test.rb +64 -0
  197. data/test/unit/queries/more_like_this_test.rb +53 -0
  198. data/test/unit/queries/multi_match_test.rb +42 -0
  199. data/test/unit/queries/nested_test.rb +50 -0
  200. data/test/unit/queries/prefix_test.rb +37 -0
  201. data/test/unit/queries/query_string_test.rb +55 -0
  202. data/test/unit/queries/range_test.rb +39 -0
  203. data/test/unit/queries/regexp_test.rb +43 -0
  204. data/test/unit/queries/simple_query_string_test.rb +43 -0
  205. data/test/unit/queries/span_first_test.rb +36 -0
  206. data/test/unit/queries/span_multi_test.rb +36 -0
  207. data/test/unit/queries/span_near_test.rb +39 -0
  208. data/test/unit/queries/span_not_test.rb +40 -0
  209. data/test/unit/queries/span_or_test.rb +36 -0
  210. data/test/unit/queries/span_term_test.rb +24 -0
  211. data/test/unit/queries/template_test.rb +43 -0
  212. data/test/unit/queries/term_test.rb +27 -0
  213. data/test/unit/queries/terms_test.rb +24 -0
  214. data/test/unit/queries/top_children_test.rb +53 -0
  215. data/test/unit/queries/wildcard_test.rb +43 -0
  216. data/test/unit/search_aggregation_test.rb +72 -0
  217. data/test/unit/search_base_aggregation_component_test.rb +41 -0
  218. data/test/unit/search_base_component_test.rb +176 -0
  219. data/test/unit/search_filter_test.rb +61 -0
  220. data/test/unit/search_highlight_test.rb +77 -0
  221. data/test/unit/search_options_test.rb +80 -0
  222. data/test/unit/search_query_test.rb +65 -0
  223. data/test/unit/search_size_from_test.rb +43 -0
  224. data/test/unit/search_sort_test.rb +40 -0
  225. data/test/unit/search_suggest_test.rb +20 -0
  226. data/test/unit/search_test.rb +201 -0
  227. data/test/unit/utils_test.rb +21 -0
  228. metadata +524 -25
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ module Elasticsearch
4
+ module Test
5
+ class NestedAggregationIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase
6
+ include Elasticsearch::DSL::Search
7
+
8
+ context "A nested aggregation" do
9
+ startup do
10
+ Elasticsearch::Extensions::Test::Cluster.start(nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?
11
+ end
12
+
13
+ setup do
14
+ @client.indices.create index: 'products-test', body: {
15
+ mappings: {
16
+ product: {
17
+ properties: {
18
+ offers: {
19
+ type: 'nested',
20
+ properties: {
21
+ name: { type: 'string' },
22
+ price: { type: 'double' }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+ }
29
+ @client.index index: 'products-test', type: 'product',
30
+ body: { title: 'A',
31
+ category: 'audio',
32
+ offers: [ { name: 'A1', price: 100 }, { name: 'A2', price: 120 } ] }
33
+ @client.index index: 'products-test', type: 'product',
34
+ body: { title: 'B',
35
+ category: 'audio',
36
+ offers: [ { name: 'B1', price: 200 }, { name: 'B2', price: 180 } ] }
37
+ @client.index index: 'products-test', type: 'product',
38
+ body: { title: 'C',
39
+ category: 'video',
40
+ offers: [ { name: 'C1', price: 300 }, { name: 'C2', price: 350 } ] }
41
+ @client.indices.refresh index: 'products-test'
42
+ end
43
+
44
+ should "return the minimal price from offers" do
45
+ response = @client.search index: 'products-test', body: search {
46
+ query { match title: 'A' }
47
+
48
+ aggregation :offers do
49
+ nested do
50
+ path 'offers'
51
+ aggregation :min_price do
52
+ min field: 'offers.price'
53
+ end
54
+ end
55
+ end
56
+ }.to_hash
57
+
58
+ assert_equal 100, response['aggregations']['offers']['min_price']['value'].to_i
59
+ end
60
+
61
+ should "return the top categories for offer price range" do
62
+ response = @client.search index: 'products-test', body: search {
63
+ query do
64
+ filtered do
65
+ filter do
66
+ nested do
67
+ path 'offers'
68
+ filter do
69
+ range 'offers.price' do
70
+ gte 100
71
+ lte 300
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ aggregation :offers do
80
+ nested do
81
+ path 'offers'
82
+ aggregation :top_categories do
83
+ reverse_nested do
84
+ aggregation :top_category_per_offer do
85
+ terms field: 'category'
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ }.to_hash
92
+
93
+ assert_equal 2, response['aggregations']['offers']['top_categories']['top_category_per_offer']['buckets'].size
94
+ assert_equal 'audio', response['aggregations']['offers']['top_categories']['top_category_per_offer']['buckets'][0]['key']
95
+ assert_equal 'video', response['aggregations']['offers']['top_categories']['top_category_per_offer']['buckets'][1]['key']
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,232 @@
1
+ require 'test_helper'
2
+
3
+ module Elasticsearch
4
+ module Test
5
+ class AggregationsIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase
6
+ include Elasticsearch::DSL::Search
7
+
8
+ context "Aggregations integration" do
9
+ setup do
10
+ @client.indices.create index: 'test'
11
+ @client.index index: 'test', type: 'd', id: '1', body: { title: 'A', tags: %w[one], clicks: 5 }
12
+ @client.index index: 'test', type: 'd', id: '2', body: { title: 'B', tags: %w[one two], clicks: 15 }
13
+ @client.index index: 'test', type: 'd', id: '3', body: { title: 'C', tags: %w[one three], clicks: 20 }
14
+ @client.indices.refresh index: 'test'
15
+ end
16
+
17
+ context "with a terms aggregation" do
18
+ should "return tag counts" do
19
+ response = @client.search index: 'test', body: search {
20
+ aggregation :tags do
21
+ terms field: 'tags'
22
+ end
23
+ }.to_hash
24
+
25
+ assert_equal 3, response['aggregations']['tags']['buckets'].size
26
+ assert_equal 'one', response['aggregations']['tags']['buckets'][0]['key']
27
+ end
28
+
29
+ should "return approximate tag counts" do
30
+ response = @client.search index: 'test', body: search {
31
+ aggregation :tags do
32
+ cardinality field: 'tags'
33
+ end
34
+ }.to_hash
35
+
36
+ assert_equal 3, response['aggregations']['tags']['value']
37
+ end
38
+
39
+ should "return tag counts per clicks range" do
40
+ response = @client.search index: 'test', body: search {
41
+ aggregation :clicks do
42
+ range field: 'clicks' do
43
+ key :low, to: 10
44
+ key :mid, from: 10, to: 20
45
+
46
+ aggregation :tags do
47
+ terms field: 'tags'
48
+ end
49
+ end
50
+ end
51
+ }.to_hash
52
+
53
+ assert_equal 2, response['aggregations']['clicks']['buckets'].size
54
+ assert_equal 1, response['aggregations']['clicks']['buckets']['low']['doc_count']
55
+ assert_equal 'one', response['aggregations']['clicks']['buckets']['low']['tags']['buckets'][0]['key']
56
+ end
57
+
58
+ should "define multiple aggregations" do
59
+ response = @client.search index: 'test', body: search {
60
+ aggregation :clicks do
61
+ range field: 'clicks' do
62
+ key :low, to: 10
63
+ key :mid, from: 10, to: 20
64
+
65
+ aggregation :tags do
66
+ terms { field 'tags' }
67
+ end
68
+ end
69
+ end
70
+
71
+ aggregation :min_clicks do
72
+ min field: 'clicks'
73
+ end
74
+
75
+ aggregation :max_clicks do
76
+ max field: 'clicks'
77
+ end
78
+
79
+ aggregation :sum_clicks do
80
+ sum field: 'clicks'
81
+ end
82
+
83
+ aggregation :avg_clicks do
84
+ avg field: 'clicks'
85
+ end
86
+ }.to_hash
87
+
88
+ assert_equal 2, response['aggregations']['clicks']['buckets'].size
89
+ assert_equal 1, response['aggregations']['clicks']['buckets']['low']['doc_count']
90
+ assert_equal 'one', response['aggregations']['clicks']['buckets']['low']['tags']['buckets'][0]['key']
91
+
92
+ assert_equal 5, response['aggregations']['min_clicks']['value']
93
+ assert_equal 20, response['aggregations']['max_clicks']['value']
94
+ assert_equal 40, response['aggregations']['sum_clicks']['value']
95
+ assert_equal 13, response['aggregations']['avg_clicks']['value'].to_i
96
+ end
97
+
98
+ should "return statistics on clicks" do
99
+ response = @client.search index: 'test', body: search {
100
+ aggregation :stats_clicks do
101
+ stats field: 'clicks'
102
+ end
103
+ aggregation :value_count do
104
+ value_count field: 'clicks'
105
+ end
106
+ }.to_hash
107
+
108
+ assert_equal 3, response['aggregations']['stats_clicks']['count']
109
+ assert_equal 5, response['aggregations']['stats_clicks']['min']
110
+ assert_equal 20, response['aggregations']['stats_clicks']['max']
111
+ assert_equal 40, response['aggregations']['stats_clicks']['sum']
112
+ assert_equal 13, response['aggregations']['stats_clicks']['avg'].to_i
113
+ assert_equal 3, response['aggregations']['value_count']['value']
114
+ end
115
+
116
+ should "return percentiles on clicks" do
117
+ response = @client.search index: 'test', body: search {
118
+ aggregation :percentiles do
119
+ percentiles field: 'clicks'
120
+ end
121
+ }.to_hash
122
+
123
+ assert_equal 20, response['aggregations']['percentiles']['values']['99.0'].round
124
+ end
125
+
126
+ should "return percentile ranks on clicks" do
127
+ response = @client.search index: 'test', body: search {
128
+ aggregation :percentiles do
129
+ percentile_ranks field: 'clicks', values: [5]
130
+ end
131
+ }.to_hash
132
+
133
+ assert_equal 17, response['aggregations']['percentiles']['values']['5.0'].round
134
+ end
135
+
136
+ should "return top hits per tag" do
137
+ response = @client.search index: 'test', body: search {
138
+ aggregation :tags do
139
+ terms do
140
+ field 'tags'
141
+ size 5
142
+
143
+ aggregation :top_hits do
144
+ top_hits sort: [ clicks: { order: 'desc' } ], _source: { include: 'title' }
145
+ end
146
+ end
147
+ end
148
+ }.to_hash
149
+
150
+ assert_equal 3, response['aggregations']['tags']['buckets'][0]['top_hits']['hits']['hits'].size
151
+ assert_equal 'C', response['aggregations']['tags']['buckets'][0]['top_hits']['hits']['hits'][0]['_source']['title']
152
+ end
153
+
154
+ should "calculate clicks for a tag" do
155
+ response = @client.search index: 'test', body: search {
156
+ aggregation :clicks_for_one do
157
+ scripted_metric do
158
+ init_script "_agg['transactions'] = []"
159
+ map_script "if (doc['tags'].value.contains('one')) { _agg.transactions.add(doc['clicks'].value) }"
160
+ combine_script "sum = 0; for (t in _agg.transactions) { sum += t }; return sum"
161
+ reduce_script "sum = 0; for (a in _aggs) { sum += a }; return sum"
162
+ end
163
+ end
164
+ }.to_hash
165
+
166
+ assert_equal 40, response['aggregations']['clicks_for_one']['value']
167
+ end
168
+
169
+ should "limit the scope with a filter" do
170
+ response = @client.search index: 'test', body: search {
171
+ aggregation :clicks_for_one do
172
+ filter terms: { tags: ['one'] } do
173
+ aggregation :sum_clicks do
174
+ sum field: 'clicks'
175
+ end
176
+ end
177
+ end
178
+ }.to_hash
179
+
180
+ assert_equal 40, response['aggregations']['clicks_for_one']['sum_clicks']['value']
181
+ end
182
+ end
183
+
184
+ should "return aggregations for multiple filters" do
185
+ response = @client.search index: 'test', body: search {
186
+ aggregation :avg_clicks_per_tag do
187
+ filters do
188
+ filters one: { terms: { tags: ['one'] } },
189
+ two: { terms: { tags: ['two'] } }
190
+ aggregation :avg do
191
+ avg field: 'clicks'
192
+ end
193
+ end
194
+ end
195
+ }.to_hash
196
+
197
+ assert_equal 13, response['aggregations']['avg_clicks_per_tag']['buckets']['one']['avg']['value'].to_i
198
+ assert_equal 15, response['aggregations']['avg_clicks_per_tag']['buckets']['two']['avg']['value'].to_i
199
+ end
200
+
201
+ should "return a histogram on clicks" do
202
+ response = @client.search index: 'test', body: search {
203
+ aggregation :clicks_histogram do
204
+ histogram do
205
+ field 'clicks'
206
+ interval 10
207
+ end
208
+ end
209
+ }.to_hash
210
+
211
+ assert_equal 3, response['aggregations']['clicks_histogram']['buckets'].size
212
+ assert_equal 10, response['aggregations']['clicks_histogram']['buckets'][1]['key']
213
+ assert_equal 1, response['aggregations']['clicks_histogram']['buckets'][1]['doc_count']
214
+ end
215
+
216
+ should "return a histogram with empty buckets on clicks" do
217
+ response = @client.search index: 'test', body: search {
218
+ aggregation :clicks_histogram do
219
+ histogram do
220
+ field 'clicks'
221
+ interval 2
222
+ min_doc_count 0
223
+ end
224
+ end
225
+ }.to_hash
226
+
227
+ assert_equal 9, response['aggregations']['clicks_histogram']['buckets'].size
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,359 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ module Elasticsearch
6
+ module Test
7
+ class FiltersIntegrationTest < ::Elasticsearch::Test::IntegrationTestCase
8
+ include Elasticsearch::DSL::Search
9
+
10
+ context "Filters integration" do
11
+ startup do
12
+ Elasticsearch::Extensions::Test::Cluster.start(nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running?
13
+ end
14
+
15
+ setup do
16
+ @client.indices.create index: 'test'
17
+ @client.index index: 'test', type: 'd', id: 1,
18
+ body: { name: 'Original',
19
+ color: 'red',
20
+ size: 'xxl',
21
+ category: 'unisex',
22
+ manufacturer: 'a' }
23
+
24
+ @client.index index: 'test', type: 'd', id: 2,
25
+ body: { name: 'Original',
26
+ color: 'red',
27
+ size: 'xl',
28
+ category: 'unisex',
29
+ manufacturer: 'a' }
30
+
31
+ @client.index index: 'test', type: 'd', id: 3,
32
+ body: { name: 'Original',
33
+ color: 'red',
34
+ size: 'l',
35
+ category: 'unisex',
36
+ manufacturer: 'a' }
37
+
38
+ @client.index index: 'test', type: 'd', id: 4,
39
+ body: { name: 'Western',
40
+ color: 'red',
41
+ size: 'm',
42
+ category: 'men',
43
+ manufacturer: 'c' }
44
+
45
+ @client.index index: 'test', type: 'd', id: 5,
46
+ body: { name: 'Modern',
47
+ color: 'grey',
48
+ size: 'l',
49
+ category: 'men',
50
+ manufacturer: 'b' }
51
+
52
+ @client.index index: 'test', type: 'd', id: 6,
53
+ body: { name: 'Modern',
54
+ color: 'grey',
55
+ size: 's',
56
+ category: 'men',
57
+ manufacturer: 'b' }
58
+
59
+ @client.index index: 'test', type: 'd', id: 7,
60
+ body: { name: 'Modern',
61
+ color: 'grey',
62
+ size: 's',
63
+ category: 'women',
64
+ manufacturer: 'b' }
65
+
66
+ @client.indices.refresh index: 'test'
67
+ end
68
+
69
+ context "term filter" do
70
+ should "return matching documents" do
71
+ response = @client.search index: 'test', body: search {
72
+ query do
73
+ filtered do
74
+ filter do
75
+ term color: 'red'
76
+ end
77
+ end
78
+ end
79
+ }.to_hash
80
+
81
+ assert_equal 4, response['hits']['total']
82
+ assert response['hits']['hits'].all? { |h| h['_source']['color'] == 'red' }, response.inspect
83
+ end
84
+ end
85
+
86
+ context "terms filter" do
87
+ should "return matching documents" do
88
+ response = @client.search index: 'test', body: search {
89
+ query do
90
+ filtered do
91
+ filter do
92
+ terms color: ['red', 'grey', 'gold']
93
+ end
94
+ end
95
+ end
96
+ }.to_hash
97
+
98
+ assert_equal 7, response['hits']['total']
99
+ end
100
+ end
101
+
102
+ context "and/or/not filters" do
103
+ should "find the document with and as a Hash" do
104
+ response = @client.search index: 'test', body: search {
105
+ query do
106
+ filtered do
107
+ filter do
108
+ _and filters: [ { term: { color: 'red' } }, { term: { size: 'xxl' } } ]
109
+ end
110
+ end
111
+ end
112
+ }.to_hash
113
+
114
+ assert_equal 1, response['hits']['total']
115
+ end
116
+
117
+ should "find the document with and as a block" do
118
+ response = @client.search index: 'test', body: search {
119
+ query do
120
+ filtered do
121
+ filter do
122
+ _and do
123
+ term color: 'red'
124
+ term size: 'xxl'
125
+ end
126
+ end
127
+ end
128
+ end
129
+ }.to_hash
130
+
131
+ assert_equal 1, response['hits']['total']
132
+ end
133
+
134
+ should "find the documents with or" do
135
+ response = @client.search index: 'test', body: search {
136
+ query do
137
+ filtered do
138
+ filter do
139
+ _or do
140
+ term size: 'l'
141
+ term size: 'm'
142
+ end
143
+ end
144
+ end
145
+ end
146
+ }.to_hash
147
+
148
+ assert_equal 3, response['hits']['total']
149
+ assert response['hits']['hits'].all? { |h| ['l', 'm'].include? h['_source']['size'] }
150
+ end
151
+
152
+ should "find the documents with not as a Hash" do
153
+ response = @client.search index: 'test', body: search {
154
+ query do
155
+ filtered do
156
+ filter do
157
+ _not term: { size: 'xxl' }
158
+ end
159
+ end
160
+ end
161
+ }.to_hash
162
+
163
+ assert_equal 6, response['hits']['total']
164
+ assert response['hits']['hits'].none? { |h| h['_source']['size'] == 'xxl' }
165
+ end
166
+
167
+ should "find the documents with not as a block" do
168
+ response = @client.search index: 'test', body: search {
169
+ query do
170
+ filtered do
171
+ filter do
172
+ _not do
173
+ term size: 'xxl'
174
+ end
175
+ end
176
+ end
177
+ end
178
+ }.to_hash
179
+
180
+ assert_equal 6, response['hits']['total']
181
+ assert response['hits']['hits'].none? { |h| h['_source']['size'] == 'xxl' }
182
+ end
183
+ end
184
+
185
+ context "bool filter" do
186
+ should "return correct documents" do
187
+ response = @client.search index: 'test', body: search {
188
+ query do
189
+ filtered do
190
+ filter do
191
+ bool do
192
+ must do
193
+ term size: 'l'
194
+ end
195
+
196
+ should do
197
+ term color: 'red'
198
+ end
199
+
200
+ should do
201
+ term category: 'men'
202
+ end
203
+
204
+ must_not do
205
+ term manufacturer: 'b'
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+ }.to_hash
212
+
213
+ assert_equal 1, response['hits']['hits'].size
214
+ assert_equal '3', response['hits']['hits'][0]['_id'].to_s
215
+ end
216
+ end
217
+
218
+ context "geographical filters" do
219
+ setup do
220
+ @client.indices.create index: 'places', body: {
221
+ mappings: {
222
+ d: {
223
+ properties: {
224
+ location: {
225
+ type: 'geo_point',
226
+ geohash: true,
227
+ geohash_prefix: true,
228
+ geohash_precision: 6
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+ @client.index index: 'places', type: 'd', id: 1,
235
+ body: { name: 'Vyšehrad',
236
+ location: '50.064399, 14.420018'}
237
+
238
+ @client.index index: 'places', type: 'd', id: 2,
239
+ body: { name: 'Karlštejn',
240
+ location: '49.939518, 14.188046'}
241
+
242
+ @client.indices.refresh index: 'places'
243
+ end
244
+
245
+ should "find documents within the bounding box" do
246
+ response = @client.search index: 'places', body: search {
247
+ query do
248
+ filtered do
249
+ filter do
250
+ geo_bounding_box :location do
251
+ top_right "50.1815123678,14.7149200439"
252
+ bottom_left "49.9415476869,14.2162566185"
253
+ end
254
+ end
255
+ end
256
+ end
257
+ }.to_hash
258
+
259
+ assert_equal 1, response['hits']['hits'].size
260
+ assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name']
261
+ end
262
+
263
+ should "find documents within the distance specified with a hash" do
264
+ response = @client.search index: 'places', body: search {
265
+ query do
266
+ filtered do
267
+ filter do
268
+ geo_distance location: '50.090223,14.399590', distance: '5km'
269
+ end
270
+ end
271
+ end
272
+ }.to_hash
273
+
274
+ assert_equal 1, response['hits']['hits'].size
275
+ assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name']
276
+ end
277
+
278
+ should "find documents within the distance specified with a block" do
279
+ response = @client.search index: 'places', body: search {
280
+ query do
281
+ filtered do
282
+ filter do
283
+ geo_distance :location do
284
+ lat '50.090223'
285
+ lon '14.399590'
286
+ distance '5km'
287
+ end
288
+ end
289
+ end
290
+ end
291
+ }.to_hash
292
+
293
+ assert_equal 1, response['hits']['hits'].size
294
+ assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name']
295
+ end
296
+
297
+ should "find documents within the geographical distance range" do
298
+ response = @client.search index: 'places', body: search {
299
+ query do
300
+ filtered do
301
+ filter do
302
+ geo_distance_range location: { lat: '50.090223', lon: '14.399590' },
303
+ gte: '10km', lte: '50km'
304
+ end
305
+ end
306
+ end
307
+ }.to_hash
308
+
309
+ assert_equal 1, response['hits']['hits'].size
310
+ assert_equal 'Karlštejn', response['hits']['hits'][0]['_source']['name']
311
+ end
312
+
313
+ should "find documents within the polygon" do
314
+ response = @client.search index: 'places', body: search {
315
+ query do
316
+ filtered do
317
+ filter do
318
+ geo_polygon :location do
319
+ points [
320
+ [14.2244355,49.9419006],
321
+ [14.2244355,50.1774301],
322
+ [14.7067869,50.1774301],
323
+ [14.7067869,49.9419006],
324
+ [14.2244355,49.9419006]
325
+ ]
326
+ end
327
+ end
328
+ end
329
+ end
330
+ }.to_hash
331
+
332
+ assert_equal 1, response['hits']['hits'].size
333
+ assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name']
334
+ end
335
+
336
+ should "find documents within the geohash cell" do
337
+ response = @client.search index: 'places', body: search {
338
+ query do
339
+ filtered do
340
+ filter do
341
+ geohash_cell :location do
342
+ lat '50.090223'
343
+ lon '14.399590'
344
+ precision '10km'
345
+ neighbors true
346
+ end
347
+ end
348
+ end
349
+ end
350
+ }.to_hash
351
+
352
+ assert_equal 1, response['hits']['hits'].size
353
+ assert_equal 'Vyšehrad', response['hits']['hits'][0]['_source']['name']
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end
359
+ end