boxplot-aggregation.asciidoc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. [role="xpack"]
  2. [testenv="basic"]
  3. [[search-aggregations-metrics-boxplot-aggregation]]
  4. === Boxplot Aggregation
  5. A `boxplot` metrics aggregation that computes boxplot of numeric values extracted from the aggregated documents.
  6. These values can be extracted either from specific numeric fields in the documents, or be generated by a provided script.
  7. The `boxplot` aggregation returns essential information for making a https://en.wikipedia.org/wiki/Box_plot[box plot]: minimum, maximum
  8. median, first quartile (25th percentile) and third quartile (75th percentile) values.
  9. ==== Syntax
  10. A `boxplot` aggregation looks like this in isolation:
  11. [source,js]
  12. --------------------------------------------------
  13. {
  14. "boxplot": {
  15. "field": "load_time"
  16. }
  17. }
  18. --------------------------------------------------
  19. // NOTCONSOLE
  20. Let's look at a boxplot representing load time:
  21. [source,console]
  22. --------------------------------------------------
  23. GET latency/_search
  24. {
  25. "size": 0,
  26. "aggs" : {
  27. "load_time_boxplot" : {
  28. "boxplot" : {
  29. "field" : "load_time" <1>
  30. }
  31. }
  32. }
  33. }
  34. --------------------------------------------------
  35. // TEST[setup:latency]
  36. <1> The field `load_time` must be a numeric field
  37. The response will look like this:
  38. [source,console-result]
  39. --------------------------------------------------
  40. {
  41. ...
  42. "aggregations": {
  43. "load_time_boxplot": {
  44. "min": 0.0,
  45. "max": 990.0,
  46. "q1": 165.0,
  47. "q2": 445.0,
  48. "q3": 725.0
  49. }
  50. }
  51. }
  52. --------------------------------------------------
  53. // TESTRESPONSE[s/\.\.\./"took": $body.took,"timed_out": false,"_shards": $body._shards,"hits": $body.hits,/]
  54. ==== Script
  55. The boxplot metric supports scripting. For example, if our load times
  56. are in milliseconds but we want values calculated in seconds, we could use
  57. a script to convert them on-the-fly:
  58. [source,console]
  59. --------------------------------------------------
  60. GET latency/_search
  61. {
  62. "size": 0,
  63. "aggs" : {
  64. "load_time_boxplot" : {
  65. "boxplot" : {
  66. "script" : {
  67. "lang": "painless",
  68. "source": "doc['load_time'].value / params.timeUnit", <1>
  69. "params" : {
  70. "timeUnit" : 1000 <2>
  71. }
  72. }
  73. }
  74. }
  75. }
  76. }
  77. --------------------------------------------------
  78. // TEST[setup:latency]
  79. <1> The `field` parameter is replaced with a `script` parameter, which uses the
  80. script to generate values which percentiles are calculated on
  81. <2> Scripting supports parameterized input just like any other script
  82. This will interpret the `script` parameter as an `inline` script with the `painless` script language and no script parameters. To use a
  83. stored script use the following syntax:
  84. [source,console]
  85. --------------------------------------------------
  86. GET latency/_search
  87. {
  88. "size": 0,
  89. "aggs" : {
  90. "load_time_boxplot" : {
  91. "boxplot" : {
  92. "script" : {
  93. "id": "my_script",
  94. "params": {
  95. "field": "load_time"
  96. }
  97. }
  98. }
  99. }
  100. }
  101. }
  102. --------------------------------------------------
  103. // TEST[setup:latency,stored_example_script]
  104. [[search-aggregations-metrics-boxplot-aggregation-approximation]]
  105. ==== Boxplot values are (usually) approximate
  106. The algorithm used by the `boxplot` metric is called TDigest (introduced by
  107. Ted Dunning in
  108. https://github.com/tdunning/t-digest/blob/master/docs/t-digest-paper/histo.pdf[Computing Accurate Quantiles using T-Digests]).
  109. [WARNING]
  110. ====
  111. Boxplot as other percentile aggregations are also
  112. https://en.wikipedia.org/wiki/Nondeterministic_algorithm[non-deterministic].
  113. This means you can get slightly different results using the same data.
  114. ====
  115. [[search-aggregations-metrics-boxplot-aggregation-compression]]
  116. ==== Compression
  117. Approximate algorithms must balance memory utilization with estimation accuracy.
  118. This balance can be controlled using a `compression` parameter:
  119. [source,console]
  120. --------------------------------------------------
  121. GET latency/_search
  122. {
  123. "size": 0,
  124. "aggs" : {
  125. "load_time_boxplot" : {
  126. "boxplot" : {
  127. "field" : "load_time",
  128. "compression" : 200 <1>
  129. }
  130. }
  131. }
  132. }
  133. --------------------------------------------------
  134. // TEST[setup:latency]
  135. <1> Compression controls memory usage and approximation error
  136. include::percentile-aggregation.asciidoc[tags=t-digest]
  137. ==== Missing value
  138. The `missing` parameter defines how documents that are missing a value should be treated.
  139. By default they will be ignored but it is also possible to treat them as if they
  140. had a value.
  141. [source,console]
  142. --------------------------------------------------
  143. GET latency/_search
  144. {
  145. "size": 0,
  146. "aggs" : {
  147. "grade_boxplot" : {
  148. "boxplot" : {
  149. "field" : "grade",
  150. "missing": 10 <1>
  151. }
  152. }
  153. }
  154. }
  155. --------------------------------------------------
  156. // TEST[setup:latency]
  157. <1> Documents without a value in the `grade` field will fall into the same bucket as documents that have the value `10`.