range-aggregation.asciidoc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. [[search-aggregations-bucket-range-aggregation]]
  2. === Range Aggregation
  3. A multi-bucket value source based aggregation that enables the user to define a set of ranges - each representing a bucket. During the aggregation process, the values extracted from each document will be checked against each bucket range and "bucket" the relevant/matching document.
  4. Note that this aggregration includes the `from` value and excludes the `to` value for each range.
  5. Example:
  6. [source,js]
  7. --------------------------------------------------
  8. {
  9. "aggs" : {
  10. "price_ranges" : {
  11. "range" : {
  12. "field" : "price",
  13. "ranges" : [
  14. { "to" : 50 },
  15. { "from" : 50, "to" : 100 },
  16. { "from" : 100 }
  17. ]
  18. }
  19. }
  20. }
  21. }
  22. --------------------------------------------------
  23. Response:
  24. [source,js]
  25. --------------------------------------------------
  26. {
  27. ...
  28. "aggregations": {
  29. "price_ranges" : {
  30. "buckets": [
  31. {
  32. "to": 50,
  33. "doc_count": 2
  34. },
  35. {
  36. "from": 50,
  37. "to": 100,
  38. "doc_count": 4
  39. },
  40. {
  41. "from": 100,
  42. "doc_count": 4
  43. }
  44. ]
  45. }
  46. }
  47. }
  48. --------------------------------------------------
  49. ==== Keyed Response
  50. Setting the `keyed` flag to `true` will associate a unique string key with each bucket and return the ranges as a hash rather than an array:
  51. [source,js]
  52. --------------------------------------------------
  53. {
  54. "aggs" : {
  55. "price_ranges" : {
  56. "range" : {
  57. "field" : "price",
  58. "keyed" : true,
  59. "ranges" : [
  60. { "to" : 50 },
  61. { "from" : 50, "to" : 100 },
  62. { "from" : 100 }
  63. ]
  64. }
  65. }
  66. }
  67. }
  68. --------------------------------------------------
  69. Response:
  70. [source,js]
  71. --------------------------------------------------
  72. {
  73. ...
  74. "aggregations": {
  75. "price_ranges" : {
  76. "buckets": {
  77. "*-50.0": {
  78. "to": 50,
  79. "doc_count": 2
  80. },
  81. "50.0-100.0": {
  82. "from": 50,
  83. "to": 100,
  84. "doc_count": 4
  85. },
  86. "100.0-*": {
  87. "from": 100,
  88. "doc_count": 4
  89. }
  90. }
  91. }
  92. }
  93. }
  94. --------------------------------------------------
  95. It is also possible to customize the key for each range:
  96. [source,js]
  97. --------------------------------------------------
  98. {
  99. "aggs" : {
  100. "price_ranges" : {
  101. "range" : {
  102. "field" : "price",
  103. "keyed" : true,
  104. "ranges" : [
  105. { "key" : "cheap", "to" : 50 },
  106. { "key" : "average", "from" : 50, "to" : 100 },
  107. { "key" : "expensive", "from" : 100 }
  108. ]
  109. }
  110. }
  111. }
  112. }
  113. --------------------------------------------------
  114. ==== Script
  115. TIP: The `script` parameter expects an inline script. Use `script_id` for indexed scripts and `script_file` for scripts in the `config/scripts/` directory.
  116. [source,js]
  117. --------------------------------------------------
  118. {
  119. "aggs" : {
  120. "price_ranges" : {
  121. "range" : {
  122. "script" : "doc['price'].value",
  123. "ranges" : [
  124. { "to" : 50 },
  125. { "from" : 50, "to" : 100 },
  126. { "from" : 100 }
  127. ]
  128. }
  129. }
  130. }
  131. }
  132. --------------------------------------------------
  133. ==== Value Script
  134. Lets say the product prices are in USD but we would like to get the price ranges in EURO. We can use value script to convert the prices prior the aggregation (assuming conversion rate of 0.8)
  135. [source,js]
  136. --------------------------------------------------
  137. {
  138. "aggs" : {
  139. "price_ranges" : {
  140. "range" : {
  141. "field" : "price",
  142. "script" : "_value * conversion_rate",
  143. "params" : {
  144. "conversion_rate" : 0.8
  145. },
  146. "ranges" : [
  147. { "to" : 35 },
  148. { "from" : 35, "to" : 70 },
  149. { "from" : 70 }
  150. ]
  151. }
  152. }
  153. }
  154. }
  155. --------------------------------------------------
  156. ==== Sub Aggregations
  157. The following example, not only "bucket" the documents to the different buckets but also computes statistics over the prices in each price range
  158. [source,js]
  159. --------------------------------------------------
  160. {
  161. "aggs" : {
  162. "price_ranges" : {
  163. "range" : {
  164. "field" : "price",
  165. "ranges" : [
  166. { "to" : 50 },
  167. { "from" : 50, "to" : 100 },
  168. { "from" : 100 }
  169. ]
  170. },
  171. "aggs" : {
  172. "price_stats" : {
  173. "stats" : { "field" : "price" }
  174. }
  175. }
  176. }
  177. }
  178. }
  179. --------------------------------------------------
  180. Response:
  181. [source,js]
  182. --------------------------------------------------
  183. {
  184. "aggregations": {
  185. "price_ranges" : {
  186. "buckets": [
  187. {
  188. "to": 50,
  189. "doc_count": 2,
  190. "price_stats": {
  191. "count": 2,
  192. "min": 20,
  193. "max": 47,
  194. "avg": 33.5,
  195. "sum": 67
  196. }
  197. },
  198. {
  199. "from": 50,
  200. "to": 100,
  201. "doc_count": 4,
  202. "price_stats": {
  203. "count": 4,
  204. "min": 60,
  205. "max": 98,
  206. "avg": 82.5,
  207. "sum": 330
  208. }
  209. },
  210. {
  211. "from": 100,
  212. "doc_count": 4,
  213. "price_stats": {
  214. "count": 4,
  215. "min": 134,
  216. "max": 367,
  217. "avg": 216,
  218. "sum": 864
  219. }
  220. }
  221. ]
  222. }
  223. }
  224. }
  225. --------------------------------------------------
  226. If a sub aggregation is also based on the same value source as the range aggregation (like the `stats` aggregation in the example above) it is possible to leave out the value source definition for it. The following will return the same response as above:
  227. [source,js]
  228. --------------------------------------------------
  229. {
  230. "aggs" : {
  231. "price_ranges" : {
  232. "range" : {
  233. "field" : "price",
  234. "ranges" : [
  235. { "to" : 50 },
  236. { "from" : 50, "to" : 100 },
  237. { "from" : 100 }
  238. ]
  239. },
  240. "aggs" : {
  241. "price_stats" : {
  242. "stats" : {} <1>
  243. }
  244. }
  245. }
  246. }
  247. }
  248. --------------------------------------------------
  249. <1> We don't need to specify the `price` as we "inherit" it by default from the parent `range` aggregation