﻿---
title: Aggregations
description: An aggregation summarizes your data as metrics, statistics, or other analytics. Aggregations help you answer questions like: What’s the average load time...
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4521/explore-analyze/query-filter/aggregations
products:
  - Elasticsearch
---

# Aggregations
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?

Elasticsearch organizes aggregations into three categories:
- [Metric](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/metrics) aggregations that calculate metrics, such as a sum or average, from field values.
- [Bucket](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/bucket) aggregations that group documents into buckets, also called bins, based on field values, ranges, or other criteria.
- [Pipeline](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/pipeline) aggregations that take input from other aggregations instead of documents or fields.


## Run an aggregation

You can run aggregations as part of a [search](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4521/solutions/search/querying-for-search) by specifying the [search API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-search)'s `aggs` parameter. The following search runs a [terms aggregation](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/search-aggregations-bucket-terms-aggregation) on `my-field`:
```json

{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}
```

Aggregation results are in the response’s `aggregations` object:
```json
{
  "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": {                           
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": []
    }
  }
}
```


## Change an aggregation’s scope

Use the `query` parameter to limit the documents on which an aggregation runs:
```json

{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "now-1d/d",
        "lt": "now/d"
      }
    }
  },
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}
```


## Return only aggregation results

By default, searches containing an aggregation return both search hits and aggregation results. To return only aggregation results, set `size` to `0`:
```json

{
  "size": 0,
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      }
    }
  }
}
```


## Run multiple aggregations

You can specify multiple aggregations in the same request:
```json

{
  "aggs": {
    "my-first-agg-name": {
      "terms": {
        "field": "my-field"
      }
    },
    "my-second-agg-name": {
      "avg": {
        "field": "my-other-field"
      }
    }
  }
}
```


## Run sub-aggregations

Bucket aggregations support bucket or metric sub-aggregations. For example, a terms aggregation with an [avg](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/search-aggregations-metrics-avg-aggregation) sub-aggregation calculates an average value for each bucket of documents. There is no level or depth limit for nesting sub-aggregations.
```json

{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      },
      "aggs": {
        "my-sub-agg-name": {
          "avg": {
            "field": "my-other-field"
          }
        }
      }
    }
  }
}
```

The response nests sub-aggregation results under their parent aggregation:
```json
{
  ...
  "aggregations": {
    "my-agg-name": {                           
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "foo",
          "doc_count": 5,
          "my-sub-agg-name": {                 
            "value": 75.0
          }
        }
      ]
    }
  }
}
```


## Add custom metadata

Use the `meta` object to associate custom metadata with an aggregation:
```json

{
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "my-field"
      },
      "meta": {
        "my-metadata-field": "foo"
      }
    }
  }
}
```

The response returns the `meta` object in place:
```json
{
  ...
  "aggregations": {
    "my-agg-name": {
      "meta": {
        "my-metadata-field": "foo"
      },
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": []
    }
  }
}
```


## Return the aggregation type

By default, aggregation results include the aggregation’s name but not its type. To return the aggregation type, use the `typed_keys` query parameter.
```json

{
  "aggs": {
    "my-agg-name": {
      "histogram": {
        "field": "my-field",
        "interval": 1000
      }
    }
  }
}
```

The response returns the aggregation type as a prefix to the aggregation’s name.
<important>
  Some aggregations return a different aggregation type from the type in the request. For example, the terms, [significant terms](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/search-aggregations-bucket-significantterms-aggregation), and [percentiles](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/search-aggregations-metrics-percentile-aggregation) aggregations return different aggregations types depending on the data type of the aggregated field.
</important>

```json
{
  ...
  "aggregations": {
    "histogram#my-agg-name": {                 
      "buckets": []
    }
  }
}
```


## Use scripts in an aggregation

When a field doesn’t exactly match the aggregation you need, you should aggregate on a [runtime field](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4521/manage-data/data-store/mapping/runtime-fields):
```json

{
  "runtime_mappings": {
    "message.length": {
      "type": "long",
      "script": "emit(doc['message.keyword'].value.length())"
    }
  },
  "aggs": {
    "message_length": {
      "histogram": {
        "interval": 10,
        "field": "message.length"
      }
    }
  }
}
```

Scripts calculate field values dynamically, which adds a little overhead to the aggregation. In addition to the time spent calculating, some aggregations like [`terms`](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/search-aggregations-bucket-terms-aggregation) and [`filters`](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/aggregations/search-aggregations-bucket-filters-aggregation) can’t use some of their optimizations with runtime fields. In total, performance costs for using a runtime field varies from aggregation to aggregation.

## Aggregation caches

For faster responses, Elasticsearch caches the results of frequently run aggregations in the [shard request cache](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/4521/deploy-manage/distributed-architecture/shard-request-cache). To get cached results, use the same [`preference` string](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/rest-apis/search-shard-routing#shard-and-node-preference) for each search. If you don’t need search hits, [set `size` to `0`](#return-only-agg-results) to avoid filling the cache.
Elasticsearch routes searches with the same preference string to the same shards. If the shards' data doesn’t change between searches, the shards return cached aggregation results.

## Limits for `long` values

When running aggregations, Elasticsearch uses [`double`](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/mapping-reference/number) values to hold and represent numeric data. As a result, aggregations on [`long`](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/mapping-reference/number) numbers greater than `2`^`53`^ are approximate.