Skip to main content
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?”
const result = await index.aggregate({
  aggregations: {
    avg_price: { $avg: { field: "price" } },
  },
});
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

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 },
//   ]
// }
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.
const result = await index.aggregate({
  filter: { inStock: true },
  aggregations: {
    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.
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 }],
      },
    },
  },
});

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.
const result = await index.aggregate({
  aggregations: {
    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.
OperatorTypical use
$avgMean value
$sumTotal
$minSmallest value
$maxLargest value
$countNumber of values
$cardinalityNumber of distinct values
$statsBasic summary stats
$extendedStatsStats + variance/std deviation
$percentilesDistribution cut points
See the metric overview.

Bucket Aggregations

Bucket aggregations partition documents into groups.
OperatorTypical use
$termsTop values by field
$rangeCustom ranges
$histogramFixed numeric bins
$dateHistogramFixed time bins
$facetHierarchical facets
See the bucket overview.