cardinality-aggregation.asciidoc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. [[search-aggregations-metrics-cardinality-aggregation]]
  2. === Cardinality Aggregation
  3. A `single-value` metrics aggregation that calculates an approximate count of
  4. distinct values. Values can be extracted either from specific fields in the
  5. document or generated by a script.
  6. Assume you are indexing books and would like to count the unique authors that
  7. match a query:
  8. [source,js]
  9. --------------------------------------------------
  10. {
  11. "aggs" : {
  12. "author_count" : {
  13. "cardinality" : {
  14. "field" : "author"
  15. }
  16. }
  17. }
  18. }
  19. --------------------------------------------------
  20. ==== Precision control
  21. This aggregation also supports the `precision_threshold` option:
  22. experimental[The `precision_threshold` option is specific to the current internal implementation of the `cardinality` agg, which may change in the future]
  23. [source,js]
  24. --------------------------------------------------
  25. {
  26. "aggs" : {
  27. "author_count" : {
  28. "cardinality" : {
  29. "field" : "author_hash",
  30. "precision_threshold": 100 <1>
  31. }
  32. }
  33. }
  34. }
  35. --------------------------------------------------
  36. <1> The `precision_threshold` options allows to trade memory for accuracy, and
  37. defines a unique count below which counts are expected to be close to
  38. accurate. Above this value, counts might become a bit more fuzzy. The maximum
  39. supported value is 40000, thresholds above this number will have the same
  40. effect as a threshold of 40000.
  41. Default value depends on the number of parent aggregations that multiple
  42. create buckets (such as terms or histograms).
  43. ==== Counts are approximate
  44. Computing exact counts requires loading values into a hash set and returning its
  45. size. This doesn't scale when working on high-cardinality sets and/or large
  46. values as the required memory usage and the need to communicate those
  47. per-shard sets between nodes would utilize too many resources of the cluster.
  48. This `cardinality` aggregation is based on the
  49. http://static.googleusercontent.com/media/research.google.com/fr//pubs/archive/40671.pdf[HyperLogLog++]
  50. algorithm, which counts based on the hashes of the values with some interesting
  51. properties:
  52. * configurable precision, which decides on how to trade memory for accuracy,
  53. * excellent accuracy on low-cardinality sets,
  54. * fixed memory usage: no matter if there are tens or billions of unique values,
  55. memory usage only depends on the configured precision.
  56. For a precision threshold of `c`, the implementation that we are using requires
  57. about `c * 8` bytes.
  58. The following chart shows how the error varies before and after the threshold:
  59. image:images/cardinality_error.png[]
  60. For all 3 thresholds, counts have been accurate up to the configured threshold
  61. (although not guaranteed, this is likely to be the case). Please also note that
  62. even with a threshold as low as 100, the error remains under 5%, even when
  63. counting millions of items.
  64. ==== Pre-computed hashes
  65. On string fields that have a high cardinality, it might be faster to store the
  66. hash of your field values in your index and then run the cardinality aggregation
  67. on this field. This can either be done by providing hash values from client-side
  68. or by letting elasticsearch compute hash values for you by using the
  69. {plugins}/mapper-size.html[`mapper-murmur3`] plugin.
  70. NOTE: Pre-computing hashes is usually only useful on very large and/or
  71. high-cardinality fields as it saves CPU and memory. However, on numeric
  72. fields, hashing is very fast and storing the original values requires as much
  73. or less memory than storing the hashes. This is also true on low-cardinality
  74. string fields, especially given that those have an optimization in order to
  75. make sure that hashes are computed at most once per unique value per segment.
  76. ==== Script
  77. The `cardinality` metric supports scripting, with a noticeable performance hit
  78. however since hashes need to be computed on the fly.
  79. [source,js]
  80. --------------------------------------------------
  81. {
  82. "aggs" : {
  83. "author_count" : {
  84. "cardinality" : {
  85. "script": "doc['author.first_name'].value + ' ' + doc['author.last_name'].value"
  86. }
  87. }
  88. }
  89. }
  90. --------------------------------------------------
  91. This will interpret the `script` parameter as an `inline` script with the default script language and no script parameters. To use a file script use the following syntax:
  92. [source,js]
  93. --------------------------------------------------
  94. {
  95. "aggs" : {
  96. "author_count" : {
  97. "cardinality" : {
  98. "script" : {
  99. "file": "my_script",
  100. "params": {
  101. "first_name_field": "author.first_name",
  102. "last_name_field": "author.last_name"
  103. }
  104. }
  105. }
  106. }
  107. }
  108. }
  109. --------------------------------------------------
  110. TIP: for indexed scripts replace the `file` parameter with an `id` parameter.
  111. ==== Missing value
  112. The `missing` parameter defines how documents that are missing a value should be treated.
  113. By default they will be ignored but it is also possible to treat them as if they
  114. had a value.
  115. [source,js]
  116. --------------------------------------------------
  117. {
  118. "aggs" : {
  119. "tag_cardinality" : {
  120. "cardinality" : {
  121. "field" : "tag",
  122. "missing": "N/A" <1>
  123. }
  124. }
  125. }
  126. }
  127. --------------------------------------------------
  128. <1> Documents without a value in the `tag` field will fall into the same bucket as documents that have the value `N/A`.