| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 | [[search-aggregations]]= Aggregations[partintro]--An aggregation summarizes your data as metrics, statistics, or other analytics.Aggregations help you answer questions like:* What's the average load time for my website?* Who are my most valuable customers based on transaction volume?* What would be considered a large file on my network?* How many products are in each product category?{es} organizes aggregations into three categories:* <<search-aggregations-metrics,Metric>> aggregations that calculate metrics,such as a sum or average, from field values.* <<search-aggregations-bucket,Bucket>> aggregations thatgroup documents into buckets, also called bins, based on field values, ranges,or other criteria.* <<search-aggregations-pipeline,Pipeline>> aggregations that take input fromother aggregations instead of documents or fields.[discrete][[run-an-agg]]=== Run an aggregationYou can run aggregations as part of a <<search-your-data,search>> by specifying the <<search-search,search API>>'s `aggs` parameter. Thefollowing search runs  a<<search-aggregations-bucket-terms-aggregation,terms aggregation>> on`my-field`:[source,console]----GET /my-index-000001/_search{  "aggs": {    "my-agg-name": {      "terms": {        "field": "my-field"      }    }  }}----// TEST[setup:my_index]// TEST[s/my-field/http.request.method/]Aggregation results are in the response's `aggregations` object:[source,console-result]----{  "took": 78,  "timed_out": false,  "_shards": {    "total": 1,    "successful": 1,    "skipped": 0,    "failed": 0  },  "hits": {    "total": {      "value": 5,      "relation": "eq"    },    "max_score": 1.0,    "hits": [...]  },  "aggregations": {    "my-agg-name": {                           <1>      "doc_count_error_upper_bound": 0,      "sum_other_doc_count": 0,      "buckets": []    }  }}----// TESTRESPONSE[s/"took": 78/"took": "$body.took"/]// TESTRESPONSE[s/\.\.\.$/"took": "$body.took", "timed_out": false, "_shards": "$body._shards", /]// TESTRESPONSE[s/"hits": \[\.\.\.\]/"hits": "$body.hits.hits"/]// TESTRESPONSE[s/"buckets": \[\]/"buckets":\[\{"key":"get","doc_count":5\}\]/]<1> Results for the `my-agg-name` aggregation.[discrete][[change-agg-scope]]=== Change an aggregation's scopeUse the `query` parameter to limit the documents on which an aggregation runs:[source,console]----GET /my-index-000001/_search{  "query": {    "range": {      "@timestamp": {        "gte": "now-1d/d",        "lt": "now/d"      }    }  },  "aggs": {    "my-agg-name": {      "terms": {        "field": "my-field"      }    }  }}----// TEST[setup:my_index]// TEST[s/my-field/http.request.method/][discrete][[return-only-agg-results]]=== Return only aggregation resultsBy default, searches containing an aggregation return both search hits andaggregation results. To return only aggregation results, set `size` to `0`:[source,console]----GET /my-index-000001/_search{  "size": 0,  "aggs": {    "my-agg-name": {      "terms": {        "field": "my-field"      }    }  }}----// TEST[setup:my_index]// TEST[s/my-field/http.request.method/][discrete][[run-multiple-aggs]]=== Run multiple aggregationsYou can specify multiple aggregations in the same request:[source,console]----GET /my-index-000001/_search{  "aggs": {    "my-first-agg-name": {      "terms": {        "field": "my-field"      }    },    "my-second-agg-name": {      "avg": {        "field": "my-other-field"      }    }  }}----// TEST[setup:my_index]// TEST[s/my-field/http.request.method/]// TEST[s/my-other-field/http.response.bytes/][discrete][[run-sub-aggs]]=== Run sub-aggregationsBucket aggregations support bucket or metric sub-aggregations. For example, aterms aggregation with an <<search-aggregations-metrics-avg-aggregation,avg>>sub-aggregation calculates an average value for each bucket of documents. Thereis no level or depth limit for nesting sub-aggregations.[source,console]----GET /my-index-000001/_search{  "aggs": {    "my-agg-name": {      "terms": {        "field": "my-field"      },      "aggs": {        "my-sub-agg-name": {          "avg": {            "field": "my-other-field"          }        }      }    }  }}----// TEST[setup:my_index]// TEST[s/_search/_search?size=0/]// TEST[s/my-field/http.request.method/]// TEST[s/my-other-field/http.response.bytes/]The response nests sub-aggregation results under their parent aggregation:[source,console-result]----{  ...  "aggregations": {    "my-agg-name": {                           <1>      "doc_count_error_upper_bound": 0,      "sum_other_doc_count": 0,      "buckets": [        {          "key": "foo",          "doc_count": 5,          "my-sub-agg-name": {                 <2>            "value": 75.0          }        }      ]    }  }}----// TESTRESPONSE[s/\.\.\./"took": "$body.took", "timed_out": false, "_shards": "$body._shards", "hits": "$body.hits",/]// TESTRESPONSE[s/"key": "foo"/"key": "get"/]// TESTRESPONSE[s/"value": 75.0/"value": $body.aggregations.my-agg-name.buckets.0.my-sub-agg-name.value/]<1> Results for the parent aggregation, `my-agg-name`.<2> Results for `my-agg-name`'s sub-aggregation, `my-sub-agg-name`.[discrete][[add-metadata-to-an-agg]]=== Add custom metadataUse the `meta` object to associate custom metadata with an aggregation:[source,console]----GET /my-index-000001/_search{  "aggs": {    "my-agg-name": {      "terms": {        "field": "my-field"      },      "meta": {        "my-metadata-field": "foo"      }    }  }}----// TEST[setup:my_index]// TEST[s/_search/_search?size=0/]The response returns the `meta` object in place:[source,console-result]----{  ...  "aggregations": {    "my-agg-name": {      "meta": {        "my-metadata-field": "foo"      },      "doc_count_error_upper_bound": 0,      "sum_other_doc_count": 0,      "buckets": []    }  }}----// TESTRESPONSE[s/\.\.\./"took": "$body.took", "timed_out": false, "_shards": "$body._shards", "hits": "$body.hits",/][discrete][[return-agg-type]]=== Return the aggregation typeBy default, aggregation results include the aggregation's name but not its type.To return the aggregation type, use the `typed_keys` query parameter.[source,console]----GET /my-index-000001/_search?typed_keys{  "aggs": {    "my-agg-name": {      "histogram": {        "field": "my-field",        "interval": 1000      }    }  }}----// TEST[setup:my_index]// TEST[s/typed_keys/typed_keys&size=0/]// TEST[s/my-field/http.response.bytes/]The response returns the aggregation type as a prefix to the aggregation's name.IMPORTANT: Some aggregations return a different aggregation type from thetype in the request. For example, the terms,<<search-aggregations-bucket-significantterms-aggregation,significant terms>>,and <<search-aggregations-metrics-percentile-aggregation,percentiles>>aggregations return different aggregations types depending on the data type ofthe aggregated field.[source,console-result]----{  ...  "aggregations": {    "histogram#my-agg-name": {                 <1>      "buckets": []    }  }}----// TESTRESPONSE[s/\.\.\./"took": "$body.took", "timed_out": false, "_shards": "$body._shards", "hits": "$body.hits",/]// TESTRESPONSE[s/"buckets": \[\]/"buckets":\[\{"key":1070000.0,"doc_count":5\}\]/]<1> The aggregation type, `histogram`, followed by a `#` separator and the aggregation's name, `my-agg-name`.[discrete][[use-scripts-in-an-agg]]=== Use scripts in an aggregationSome aggregations support <<modules-scripting,scripts>>. You canuse a `script` to extract or generate values for the aggregation:[source,console]----GET /my-index-000001/_search{  "aggs": {    "my-agg-name": {      "histogram": {        "interval": 1000,        "script": {          "source": "doc['my-field'].value.length()"        }      }    }  }}----// TEST[setup:my_index]// TEST[s/my-field/http.request.method/]If you also specify a `field`, the `script` modifies the field values used inthe aggregation. The following aggregation uses a script to modify `my-field`values:[source,console]----GET /my-index-000001/_search{  "aggs": {    "my-agg-name": {      "histogram": {        "field": "my-field",        "interval": 1000,        "script": "_value / 1000"      }    }  }}----// TEST[setup:my_index]// TEST[s/my-field/http.response.bytes/]Some aggregations only work on specific data types. Use the `value_type`parameter to specify a data type for a script-generated value or an unmappedfield. `value_type` accepts the following values:* `boolean`* `date`* `double`, used for all floating-point numbers* `long`, used for all integers* `ip`* `string`[source,console]----GET /my-index-000001/_search{  "aggs": {    "my-agg-name": {      "histogram": {        "field": "my-field",        "interval": 1000,        "script": "_value / 1000",        "value_type": "long"      }    }  }}----// TEST[setup:my_index]// TEST[s/my-field/http.response.bytes/][discrete][[agg-caches]]=== Aggregation cachesFor faster responses, {es} caches the results of frequently run aggregations inthe <<shard-request-cache,shard request cache>>. To get cached results, use thesame <<shard-and-node-preference,`preference` string>> for each search. If youdon't need search hits, <<return-only-agg-results,set `size` to `0`>> to avoidfilling the cache.{es} routes searches with the same preference string to the same shards. If theshards' data doesn’t change between searches, the shards return cachedaggregation results.[discrete][[limits-for-long-values]]=== Limits for `long` valuesWhen running aggregations, {es} uses <<number,`double`>> values to hold andrepresent numeric data. As a result, aggregations on <<number,`long`>> numbersgreater than +2^53^+ are approximate.--include::aggregations/bucket.asciidoc[]include::aggregations/metrics.asciidoc[]include::aggregations/pipeline.asciidoc[]
 |