# Aggregations

Aggregations let you compute analytics over your indexed data — metrics like averages, sums, and statistics,
as well as bucket-based groupings like terms, ranges, and histograms.

They are useful when you want to answer questions like:

- "What is the average price?"
- "How many unique users do we have?"
- "How many orders fall into each price range?"
- "How does traffic change per hour/day?"

<Tabs>

<Tab title="TypeScript">
```ts
const result = await index.aggregate({
  aggregations: {
    avg_price: { $avg: { field: "price" } },
  },
});
```
</Tab>

<Tab title="Python">
```python
result = index.aggregate(
    aggregations={"avg_price": {"$avg": {"field": "price"}}},
)
```
</Tab>

<Tab title="Redis CLI">
```bash
SEARCH.AGGREGATE products '{}' '{"avg_price": {"$avg": {"field": "price"}}}'
```
</Tab>

</Tabs>

Aggregation requests have two phases:

1. **Document selection**: Optional `filter` selects which documents participate.
2. **Aggregation computation**: the selected set is reduced into metric values and/or buckets.

Each aggregation is defined with an **alias** (the key you choose for the result) and an **operator** that specifies what to compute.

### Response Format

<Tabs>

<Tab title="TypeScript">
```ts
const result = await index.aggregate({
  aggregations: {
    avg_price: { $avg: { field: "price" } },
    by_category: { $terms: { field: "category", size: 5 } },
  },
});

// result is an object keyed by alias:
// {
//   avg_price: { value: 49.99 },
//   by_category: {
//     buckets: [
//       { key: "electronics", docCount: 42 },
//       { key: "clothing", docCount: 31 },
//     ],
//   },
// }
```
</Tab>

<Tab title="Python">
```python
result = index.aggregate(
    aggregations={
        "avg_price": {"$avg": {"field": "price"}},
        "by_category": {"$terms": {"field": "category", "size": 5}},
    },
)

# result is a dict keyed by alias:
# {
#   "avg_price": {"value": 49.99},
#   "by_category": {
#     "buckets": [
#       {"key": "electronics", "docCount": 42},
#       {"key": "clothing", "docCount": 31},
#     ],
#   },
# }
```
</Tab>

<Tab title="Redis CLI">
```bash
SEARCH.AGGREGATE products '{}' '{"avg_price": {"$avg": {"field": "price"}}, "by_category": {"$terms": {"field": "category", "size": 5}}}'

# Response (`redis-cli --json`) is an object keyed by alias:
# {"avg_price":{"value":49.99},"by_category":{"buckets":[{"key":"electronics","docCount":42},{"key":"clothing","docCount":31}]}}
```
</Tab>

</Tabs>

## Filtering

Use `filter` to restrict which documents participate in the aggregation.

Filtering uses the same query syntax as [queries](./querying).

<Tabs>

<Tab title="TypeScript">
```ts
const result = await index.aggregate({
  filter: { inStock: true },
  aggregations: {
    avg_price: { $avg: { field: "price" } },
  },
});
```
</Tab>

<Tab title="Python">
```python
result = index.aggregate(
    filter={"inStock": True},
    aggregations={
        "avg_price": {"$avg": {"field": "price"}},
    },
)
```
</Tab>

<Tab title="Redis CLI">
```bash
SEARCH.AGGREGATE products '{"inStock": true}' '{"avg_price": {"$avg": {"field": "price"}}}'
```
</Tab>

</Tabs>

## Multiple Aggregations in One Request

You can compute multiple top-level aggregations in one call by defining multiple aliases under `aggregations`.

Each alias is computed against the same filtered document set.

<Tabs>

<Tab title="TypeScript">
```ts
const result = await index.aggregate({
  aggregations: {
    avg_price: { $avg: { field: "price" } },
    price_stats: { $stats: { field: "price" } },
    by_category: { $terms: { field: "category", size: 5 } },
    price_ranges: {
      $range: {
        field: "price",
        ranges: [{ to: 50 }, { from: 50 }],
      },
    },
  },
});
```
</Tab>

<Tab title="Python">
```python
result = index.aggregate(
    aggregations={
        "avg_price": {"$avg": {"field": "price"}},
        "price_stats": {"$stats": {"field": "price"}},
        "by_category": {"$terms": {"field": "category", "size": 5}},
        "price_ranges": {
            "$range": {
                "field": "price",
                "ranges": [{"to": 50}, {"from": 50}],
            }
        },
    },
)
```
</Tab>

<Tab title="Redis CLI">
```bash
SEARCH.AGGREGATE products '{}' '{"avg_price": {"$avg": {"field": "price"}}, "price_stats": {"$stats": {"field": "price"}}, "by_category": {"$terms": {"field": "category", "size": 5}}, "price_ranges": {"$range": {"field": "price", "ranges": [{"to": 50}, {"from": 50}]}}}'
```
</Tab>

</Tabs>

## Nested Aggregations

Bucket operators can include sub-aggregations via `$aggs`, so you can compute per-bucket metrics.

- `$terms`, `$range`, `$histogram`, and `$dateHistogram` support nested `$aggs`.
- `$facet` does not support nested `$aggs`.
- Metric operators do not support nested `$aggs`.

<Tabs>

<Tab title="TypeScript">
```ts
const result = await index.aggregate({
  aggregations: {
    by_category: {
      $terms: { field: "category" },
      $aggs: {
        avg_price: { $avg: { field: "price" } },
        min_price: { $min: { field: "price" } },
      },
    },
  },
});
```
</Tab>

<Tab title="Python">
```python
result = index.aggregate(
    aggregations={
        "by_category": {
            "$terms": {"field": "category"},
            "$aggs": {
                "avg_price": {"$avg": {"field": "price"}},
                "min_price": {"$min": {"field": "price"}},
            },
        },
    },
)
```
</Tab>

<Tab title="Redis CLI">
```bash
SEARCH.AGGREGATE products '{}' '{"by_category": {"$terms": {"field": "category"}, "$aggs": {"avg_price": {"$avg": {"field": "price"}}, "min_price": {"$min": {"field": "price"}}}}}'
```
</Tab>

</Tabs>

## Operator Families

### Metric Aggregations

Metric aggregations return numeric summaries.

| Operator | Typical use |
|----------|-------------|
| [`$avg`](./aggregation-operators/metric-aggregations/avg) | Mean value |
| [`$sum`](./aggregation-operators/metric-aggregations/sum) | Total |
| [`$min`](./aggregation-operators/metric-aggregations/min) | Smallest value |
| [`$max`](./aggregation-operators/metric-aggregations/max) | Largest value |
| [`$count`](./aggregation-operators/metric-aggregations/count) | Number of values |
| [`$cardinality`](./aggregation-operators/metric-aggregations/cardinality) | Number of distinct values |
| [`$stats`](./aggregation-operators/metric-aggregations/stats) | Basic summary stats |
| [`$extendedStats`](./aggregation-operators/metric-aggregations/extended-stats) | Stats + variance/std deviation |
| [`$percentiles`](./aggregation-operators/metric-aggregations/percentiles) | Distribution cut points |

See the [metric overview](./aggregation-operators/metric-aggregations/overview).

### Bucket Aggregations

Bucket aggregations partition documents into groups.

| Operator | Typical use |
|----------|-------------|
| [`$terms`](./aggregation-operators/bucket-aggregations/terms) | Top values by field |
| [`$range`](./aggregation-operators/bucket-aggregations/range) | Custom ranges |
| [`$histogram`](./aggregation-operators/bucket-aggregations/histogram) | Fixed numeric bins |
| [`$dateHistogram`](./aggregation-operators/bucket-aggregations/date-histogram) | Fixed time bins |
| [`$facet`](./aggregation-operators/bucket-aggregations/facet) | Hierarchical facets |

See the [bucket overview](./aggregation-operators/bucket-aggregations/overview).
