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?”
TypeScript
Python
Redis CLI
const result = await index.aggregate({
aggregations: {
avg_price: { $avg: { field: "price" } },
},
});
result = index.aggregate(
aggregations={"avg_price": {"$avg": {"field": "price"}}},
)
SEARCH.AGGREGATE products '{}' '{"avg_price": {"$avg": {"field": "price"}}}'
Aggregation requests have two phases:
- Document selection: Optional
filter selects which documents participate.
- 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.
TypeScript
Python
Redis CLI
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: 49.99,
// by_category: [
// { key: "electronics", docCount: 42 },
// { key: "clothing", docCount: 31 },
// ]
// }
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": 49.99,
# "by_category": [
# {"key": "electronics", "doc_count": 42},
# {"key": "clothing", "doc_count": 31},
# ]
# }
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}]}}
Each SDK normalizes response keys to match its language’s conventions: camelCase for TypeScript
(e.g., docCount) and snake_case for Python (e.g., doc_count). In redis-cli --json, Redis CLI
returns a JSON object keyed by aggregation alias.
All metric aggregation operators require the target field to be marked as FAST in your schema.
If the field is not FAST, you will get an error like:
Aggregation '<name>' operator '$avg' requires field '<field>' to be FAST.
See FAST Fields for details.
Filtering
Use filter to restrict which documents participate in the aggregation.
Filtering uses the same query syntax as queries.
TypeScript
Python
Redis CLI
const result = await index.aggregate({
filter: { inStock: true },
aggregations: {
avg_price: { $avg: { field: "price" } },
},
});
result = index.aggregate(
filter={"inStock": True},
aggregations={
"avg_price": {"$avg": {"field": "price"}},
},
)
SEARCH.AGGREGATE products '{"inStock": true}' '{"avg_price": {"$avg": {"field": "price"}}}'
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.
TypeScript
Python
Redis CLI
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 }],
},
},
},
});
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}],
}
},
},
)
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}]}}}'
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.
TypeScript
Python
Redis CLI
const result = await index.aggregate({
aggregations: {
by_category: {
$terms: { field: "category" },
$aggs: {
avg_price: { $avg: { field: "price" } },
min_price: { $min: { field: "price" } },
},
},
},
});
result = index.aggregate(
aggregations={
"by_category": {
"$terms": {"field": "category"},
"$aggs": {
"avg_price": {"$avg": {"field": "price"}},
"min_price": {"$min": {"field": "price"}},
},
},
},
)
SEARCH.AGGREGATE products '{}' '{"by_category": {"$terms": {"field": "category"}, "$aggs": {"avg_price": {"$avg": {"field": "price"}}, "min_price": {"$min": {"field": "price"}}}}}'
Operator Families
Metric Aggregations
Metric aggregations return numeric summaries.
| Operator | Typical use |
|---|
$avg | Mean value |
$sum | Total |
$min | Smallest value |
$max | Largest value |
$count | Number of values |
$cardinality | Number of distinct values |
$stats | Basic summary stats |
$extendedStats | Stats + variance/std deviation |
$percentiles | Distribution cut points |
See the metric overview.
Bucket Aggregations
Bucket aggregations partition documents into groups.
| Operator | Typical use |
|---|
$terms | Top values by field |
$range | Custom ranges |
$histogram | Fixed numeric bins |
$dateHistogram | Fixed time bins |
$facet | Hierarchical facets |
See the bucket overview.