rate-aggregation.asciidoc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. [role="xpack"]
  2. [testenv="basic"]
  3. [[search-aggregations-metrics-rate-aggregation]]
  4. === Rate aggregation
  5. ++++
  6. <titleabbrev>Rate</titleabbrev>
  7. ++++
  8. A `rate` metrics aggregation can be used only inside a `date_histogram` or `composite` aggregation. It calculates a rate of documents
  9. or a field in each bucket. The field values can be generated extracted from specific numeric or
  10. <<histogram,histogram fields>> in the documents.
  11. NOTE: For `composite` aggregations, there must be exactly one `date_histogram` source for the `rate` aggregation to be supported.
  12. ==== Syntax
  13. A `rate` aggregation looks like this in isolation:
  14. [source,js]
  15. --------------------------------------------------
  16. {
  17. "rate": {
  18. "unit": "month",
  19. "field": "requests"
  20. }
  21. }
  22. --------------------------------------------------
  23. // NOTCONSOLE
  24. The following request will group all sales records into monthly bucket and than convert the number of sales transaction in each bucket
  25. into per annual sales rate.
  26. [source,console]
  27. --------------------------------------------------
  28. GET sales/_search
  29. {
  30. "size": 0,
  31. "aggs": {
  32. "by_date": {
  33. "date_histogram": {
  34. "field": "date",
  35. "calendar_interval": "month" <1>
  36. },
  37. "aggs": {
  38. "my_rate": {
  39. "rate": {
  40. "unit": "year" <2>
  41. }
  42. }
  43. }
  44. }
  45. }
  46. }
  47. --------------------------------------------------
  48. // TEST[setup:sales]
  49. <1> Histogram is grouped by month.
  50. <2> But the rate is converted into annual rate.
  51. The response will return the annual rate of transaction in each bucket. Since there are 12 months per year, the annual rate will
  52. be automatically calculated by multiplying monthly rate by 12.
  53. [source,console-result]
  54. --------------------------------------------------
  55. {
  56. ...
  57. "aggregations" : {
  58. "by_date" : {
  59. "buckets" : [
  60. {
  61. "key_as_string" : "2015/01/01 00:00:00",
  62. "key" : 1420070400000,
  63. "doc_count" : 3,
  64. "my_rate" : {
  65. "value" : 36.0
  66. }
  67. },
  68. {
  69. "key_as_string" : "2015/02/01 00:00:00",
  70. "key" : 1422748800000,
  71. "doc_count" : 2,
  72. "my_rate" : {
  73. "value" : 24.0
  74. }
  75. },
  76. {
  77. "key_as_string" : "2015/03/01 00:00:00",
  78. "key" : 1425168000000,
  79. "doc_count" : 2,
  80. "my_rate" : {
  81. "value" : 24.0
  82. }
  83. }
  84. ]
  85. }
  86. }
  87. }
  88. --------------------------------------------------
  89. // TESTRESPONSE[s/\.\.\./"took": $body.took,"timed_out": false,"_shards": $body._shards,"hits": $body.hits,/]
  90. Instead of counting the number of documents, it is also possible to calculate a sum of all values of the fields in the documents in each
  91. bucket or the number of values in each bucket. The following request will group all sales records into monthly bucket and than calculate
  92. the total monthly sales and convert them into average daily sales.
  93. [source,console]
  94. --------------------------------------------------
  95. GET sales/_search
  96. {
  97. "size": 0,
  98. "aggs": {
  99. "by_date": {
  100. "date_histogram": {
  101. "field": "date",
  102. "calendar_interval": "month" <1>
  103. },
  104. "aggs": {
  105. "avg_price": {
  106. "rate": {
  107. "field": "price", <2>
  108. "unit": "day" <3>
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }
  115. --------------------------------------------------
  116. // TEST[setup:sales]
  117. <1> Histogram is grouped by month.
  118. <2> Calculate sum of all sale prices
  119. <3> Convert to average daily sales
  120. The response will contain the average daily sale prices for each month.
  121. [source,console-result]
  122. --------------------------------------------------
  123. {
  124. ...
  125. "aggregations" : {
  126. "by_date" : {
  127. "buckets" : [
  128. {
  129. "key_as_string" : "2015/01/01 00:00:00",
  130. "key" : 1420070400000,
  131. "doc_count" : 3,
  132. "avg_price" : {
  133. "value" : 17.741935483870968
  134. }
  135. },
  136. {
  137. "key_as_string" : "2015/02/01 00:00:00",
  138. "key" : 1422748800000,
  139. "doc_count" : 2,
  140. "avg_price" : {
  141. "value" : 2.142857142857143
  142. }
  143. },
  144. {
  145. "key_as_string" : "2015/03/01 00:00:00",
  146. "key" : 1425168000000,
  147. "doc_count" : 2,
  148. "avg_price" : {
  149. "value" : 12.096774193548388
  150. }
  151. }
  152. ]
  153. }
  154. }
  155. }
  156. --------------------------------------------------
  157. // TESTRESPONSE[s/\.\.\./"took": $body.took,"timed_out": false,"_shards": $body._shards,"hits": $body.hits,/]
  158. You can also take advantage of `composite` aggregations to calculate the average daily sale price for each item in
  159. your inventory
  160. [source,console]
  161. --------------------------------------------------
  162. GET sales/_search?filter_path=aggregations&size=0
  163. {
  164. "aggs": {
  165. "buckets": {
  166. "composite": { <1>
  167. "sources": [
  168. {
  169. "month": {
  170. "date_histogram": { <2>
  171. "field": "date",
  172. "calendar_interval": "month"
  173. }
  174. }
  175. },
  176. {
  177. "type": { <3>
  178. "terms": {
  179. "field": "type"
  180. }
  181. }
  182. }
  183. ]
  184. },
  185. "aggs": {
  186. "avg_price": {
  187. "rate": {
  188. "field": "price", <4>
  189. "unit": "day" <5>
  190. }
  191. }
  192. }
  193. }
  194. }
  195. }
  196. --------------------------------------------------
  197. // TEST[setup:sales]
  198. <1> Composite aggregation with a date histogram source
  199. and a source for the item type.
  200. <2> The date histogram source grouping monthly
  201. <3> The terms source grouping for each sale item type
  202. <4> Calculate sum of all sale prices, per month and item
  203. <5> Convert to average daily sales per item
  204. The response will contain the average daily sale prices for each month per item.
  205. [source,console-result]
  206. --------------------------------------------------
  207. {
  208. "aggregations" : {
  209. "buckets" : {
  210. "after_key" : {
  211. "month" : 1425168000000,
  212. "type" : "t-shirt"
  213. },
  214. "buckets" : [
  215. {
  216. "key" : {
  217. "month" : 1420070400000,
  218. "type" : "bag"
  219. },
  220. "doc_count" : 1,
  221. "avg_price" : {
  222. "value" : 4.838709677419355
  223. }
  224. },
  225. {
  226. "key" : {
  227. "month" : 1420070400000,
  228. "type" : "hat"
  229. },
  230. "doc_count" : 1,
  231. "avg_price" : {
  232. "value" : 6.451612903225806
  233. }
  234. },
  235. {
  236. "key" : {
  237. "month" : 1420070400000,
  238. "type" : "t-shirt"
  239. },
  240. "doc_count" : 1,
  241. "avg_price" : {
  242. "value" : 6.451612903225806
  243. }
  244. },
  245. {
  246. "key" : {
  247. "month" : 1422748800000,
  248. "type" : "hat"
  249. },
  250. "doc_count" : 1,
  251. "avg_price" : {
  252. "value" : 1.7857142857142858
  253. }
  254. },
  255. {
  256. "key" : {
  257. "month" : 1422748800000,
  258. "type" : "t-shirt"
  259. },
  260. "doc_count" : 1,
  261. "avg_price" : {
  262. "value" : 0.35714285714285715
  263. }
  264. },
  265. {
  266. "key" : {
  267. "month" : 1425168000000,
  268. "type" : "hat"
  269. },
  270. "doc_count" : 1,
  271. "avg_price" : {
  272. "value" : 6.451612903225806
  273. }
  274. },
  275. {
  276. "key" : {
  277. "month" : 1425168000000,
  278. "type" : "t-shirt"
  279. },
  280. "doc_count" : 1,
  281. "avg_price" : {
  282. "value" : 5.645161290322581
  283. }
  284. }
  285. ]
  286. }
  287. }
  288. }
  289. --------------------------------------------------
  290. By adding the `mode` parameter with the value `value_count`, we can change the calculation from `sum` to the number of values of the field:
  291. [source,console]
  292. --------------------------------------------------
  293. GET sales/_search
  294. {
  295. "size": 0,
  296. "aggs": {
  297. "by_date": {
  298. "date_histogram": {
  299. "field": "date",
  300. "calendar_interval": "month" <1>
  301. },
  302. "aggs": {
  303. "avg_number_of_sales_per_year": {
  304. "rate": {
  305. "field": "price", <2>
  306. "unit": "year", <3>
  307. "mode": "value_count" <4>
  308. }
  309. }
  310. }
  311. }
  312. }
  313. }
  314. --------------------------------------------------
  315. // TEST[setup:sales]
  316. <1> Histogram is grouped by month.
  317. <2> Calculate number of all sale prices
  318. <3> Convert to annual counts
  319. <4> Changing the mode to value count
  320. The response will contain the average daily sale prices for each month.
  321. [source,console-result]
  322. --------------------------------------------------
  323. {
  324. ...
  325. "aggregations" : {
  326. "by_date" : {
  327. "buckets" : [
  328. {
  329. "key_as_string" : "2015/01/01 00:00:00",
  330. "key" : 1420070400000,
  331. "doc_count" : 3,
  332. "avg_number_of_sales_per_year" : {
  333. "value" : 36.0
  334. }
  335. },
  336. {
  337. "key_as_string" : "2015/02/01 00:00:00",
  338. "key" : 1422748800000,
  339. "doc_count" : 2,
  340. "avg_number_of_sales_per_year" : {
  341. "value" : 24.0
  342. }
  343. },
  344. {
  345. "key_as_string" : "2015/03/01 00:00:00",
  346. "key" : 1425168000000,
  347. "doc_count" : 2,
  348. "avg_number_of_sales_per_year" : {
  349. "value" : 24.0
  350. }
  351. }
  352. ]
  353. }
  354. }
  355. }
  356. --------------------------------------------------
  357. // TESTRESPONSE[s/\.\.\./"took": $body.took,"timed_out": false,"_shards": $body._shards,"hits": $body.hits,/]
  358. By default `sum` mode is used.
  359. `"mode": "sum"`:: calculate the sum of all values field
  360. `"mode": "value_count"`:: use the number of values in the field
  361. ==== Relationship between bucket sizes and rate
  362. The `rate` aggregation supports all rate that can be used <<calendar_intervals,calendar_intervals parameter>> of `date_histogram`
  363. aggregation. The specified rate should compatible with the `date_histogram` aggregation interval, i.e. it should be possible to
  364. convert the bucket size into the rate. By default the interval of the `date_histogram` is used.
  365. `"rate": "second"`:: compatible with all intervals
  366. `"rate": "minute"`:: compatible with all intervals
  367. `"rate": "hour"`:: compatible with all intervals
  368. `"rate": "day"`:: compatible with all intervals
  369. `"rate": "week"`:: compatible with all intervals
  370. `"rate": "month"`:: compatible with only with `month`, `quarter` and `year` calendar intervals
  371. `"rate": "quarter"`:: compatible with only with `month`, `quarter` and `year` calendar intervals
  372. `"rate": "year"`:: compatible with only with `month`, `quarter` and `year` calendar intervals
  373. There is also an additional limitations if the date histogram is not a direct parent of the rate histogram. In this case both rate interval
  374. and histogram interval have to be in the same group: [`second`, ` minute`, `hour`, `day`, `week`] or [`month`, `quarter`, `year`]. For
  375. example, if the date histogram is `month` based, only rate intervals of `month`, `quarter` or `year` are supported. If the date histogram
  376. is `day` based, only `second`, ` minute`, `hour`, `day`, and `week` rate intervals are supported.
  377. ==== Script
  378. If you need to run the aggregation against values that aren't indexed, run the
  379. aggregation on a <<runtime,runtime field>>. For example, if we need to adjust
  380. our prices before calculating rates:
  381. [source,console]
  382. ----
  383. GET sales/_search
  384. {
  385. "size": 0,
  386. "runtime_mappings": {
  387. "price.adjusted": {
  388. "type": "double",
  389. "script": {
  390. "source": "emit(doc['price'].value * params.adjustment)",
  391. "params": {
  392. "adjustment": 0.9
  393. }
  394. }
  395. }
  396. },
  397. "aggs": {
  398. "by_date": {
  399. "date_histogram": {
  400. "field": "date",
  401. "calendar_interval": "month"
  402. },
  403. "aggs": {
  404. "avg_price": {
  405. "rate": {
  406. "field": "price.adjusted"
  407. }
  408. }
  409. }
  410. }
  411. }
  412. }
  413. ----
  414. // TEST[setup:sales]
  415. [source,console-result]
  416. ----
  417. {
  418. ...
  419. "aggregations" : {
  420. "by_date" : {
  421. "buckets" : [
  422. {
  423. "key_as_string" : "2015/01/01 00:00:00",
  424. "key" : 1420070400000,
  425. "doc_count" : 3,
  426. "avg_price" : {
  427. "value" : 495.0
  428. }
  429. },
  430. {
  431. "key_as_string" : "2015/02/01 00:00:00",
  432. "key" : 1422748800000,
  433. "doc_count" : 2,
  434. "avg_price" : {
  435. "value" : 54.0
  436. }
  437. },
  438. {
  439. "key_as_string" : "2015/03/01 00:00:00",
  440. "key" : 1425168000000,
  441. "doc_count" : 2,
  442. "avg_price" : {
  443. "value" : 337.5
  444. }
  445. }
  446. ]
  447. }
  448. }
  449. }
  450. ----
  451. // TESTRESPONSE[s/\.\.\./"took": $body.took,"timed_out": false,"_shards": $body._shards,"hits": $body.hits,/]