/aggregating
Run analytics over indexed data using metric and bucket aggregations. Compute statistics, group documents, build histograms, and perform faceted navigation. Aggregations can be nested for multi-level analysis.
How it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/aggregating
Context preview
What this command does when you run it.
Run analytics over indexed data using metric and bucket aggregations. Compute statistics, group documents, build histograms, and perform faceted navigation. Aggregations can be nested for multi-level analysis.
Command definition
aggregating.mdAggregations
Overview
Run analytics over indexed data using metric and bucket aggregations. Compute statistics, group documents, build histograms, and perform faceted navigation. Aggregations can be nested for multi-level analysis.
Good For
- Computing averages, sums, min/max across documents
- Grouping documents by field values (category breakdown)
- Building price range facets for e-commerce
- Histogram distributions (price ranges, date ranges)
- Multi-level analytics (average price per category)
Examples
Metric Aggregations
import { Redis, s } from "@upstash/redis";
const redis = Redis.fromEnv();
const index = await redis.search.createIndex({
name: "orders",
prefix: "order:",
dataType: "json",
schema: s.object({
product: s.string(),
category: s.facet(),
price: s.number("F64"),
quantity: s.number("U64"),
date: s.date(),
}),
});
// Insert sample data
await redis.json.set("order:1", "$", {
product: "Laptop",
category: "electronics",
price: 999.99,
quantity: 1,
date: "2024-06-15",
});
await redis.json.set("order:2", "$", {
product: "Mouse",
category: "electronics",
price: 29.99,
quantity: 3,
date: "2024-06-16",
});
await redis.json.set("order:3", "$", {
product: "Desk",
category: "furniture",
price: 249.99,
quantity: 1,
date: "2024-07-01",
});
await index.waitIndexing();
// Average price
const result = await index.aggregate({
aggregations: {
avg_price: { $avg: { field: "price" } },
},
});
// result.avg_price -> number
// Multiple metrics at once
const stats = await index.aggregate({
aggregations: {
avg_price: { $avg: { field: "price" } },
total_revenue: { $sum: { field: "price" } },
cheapest: { $min: { field: "price" } },
most_expensive: { $max: { field: "price" } },
order_count: { $count: { field: "price" } },
},
});
// Combined statistics
const priceStats = await index.aggregate({
aggregations: {
price_stats: { $stats: { field: "price" } },
// Returns: { count, min, max, sum, avg }
},
});
// Extended statistics (includes variance and standard deviation)
const extended = await index.aggregate({
aggregations: {
price_extended: { $extendedStats: { field: "price" } },
// Returns: { count, min, max, sum, avg, sumOfSquares, variance, stdDeviation }
},
});
// Percentiles
const percentiles = await index.aggregate({
aggregations: {
price_percentiles: { $percentiles: { field: "price", percents: [25, 50, 75, 95] } },
},
});
// Count distinct values
const uniqueCategories = await index.aggregate({
aggregations: {
unique_cats: { $cardinality: { field: "category" } },
},
});Bucket Aggregations
$terms - Group by field values
const byCategory = await index.aggregate({
aggregations: {
categories: {
$terms: { field: "category", size: 10 },
},
},
});
// categories.buckets -> [{ key: "electronics", doc_count: 2 }, { key: "furniture", doc_count: 1 }]$range - Group by numeric ranges
const priceRanges = await index.aggregate({
aggregations: {
price_ranges: {
$range: {
field: "price",
ranges: [
{ to: 50 }, // Under $50
{ from: 50, to: 200 }, // $50-$200
{ from: 200 }, // Over $200
],
},
},
},
});$histogram - Fixed-interval numeric buckets
const priceHistogram = await index.aggregate({
aggregations: {
price_distribution: {
$histogram: { field: "price", interval: 100 },
},
},
});$facet - Faceted navigation
const facets = await index.aggregate({
aggregations: {
brand_facets: { $facet: { field: "brand" } },
},
});Nested Aggregations
Combine buckets with metrics for multi-level analysis:
// Average price per category
const result = await index.aggregate({
aggregations: {
by_category: {
$terms: { field: "category" },
$aggs: {
avg_price: { $avg: { field: "price" } },
min_price: { $min: { field: "price" } },
max_price: { $max: { field: "price" } },
total_orders: { $count: { field: "price" } },
},
},
},
});
// by_category.buckets -> [
// { key: "electronics", doc_count: 2, avg_price: 514.99, min_price: 29.99, max_price: 999.99, total_orders: 2 },
// { key: "furniture", doc_count: 1, avg_price: 249.99, ... },
// ]Filtered Aggregations
Apply a filter before aggregating:
const electronicsStats = await index.aggregate({
filter: { category: { $eq: "electronics" } },
aggregations: {
avg_price: { $avg: { field: "price" } },
price_ranges: {
$range: {
field: "price",
ranges: [{ to: 100 }, { from: 100, to: 500 }, { from: 500 }],
},
},
},
});Available Aggregations
Metric Aggregations
| Aggregation | Description | | ---------------- | ------------------------------------------ | | `$avg` | Average value of a numeric field | | `$sum` | Sum of values | | `$min` | Minimum value | | `$max` | Maximum value | | `$count` | Count of documents | | `$cardinality` | Count of distinct values | | `$stats` | Combined count/min/max/sum/avg | | `$extendedStats` | Stats + variance/stdDeviation/sumOfSquares | | `$percentiles` | Percentile values at specified thresholds |
Bucket Aggregations
| Aggregation | Description | | ------------ | --------------------------------- | | `$terms` | Group by field values | | `$range` | Group by custom numeric ranges | | `$histogram` | Fixed-interval numeric buckets | | `$facet` | Faceted navigation (hierarchical) |
Read more
Aggregations
Overview
Run analytics over indexed data using metric and bucket aggregations. Compute statistics, group documents, build histograms, and perform faceted navigation. Aggregations can be nested for multi-level analysis.
Good For
- Computing averages, sums, min/max across documents
- Grouping documents by field values (category breakdown)
- Building price range facets for e-commerce
- Histogram distributions (price ranges, date ranges)
- Multi-level analytics (average price per category)
Examples
Metric Aggregations
import { Redis, s } from "@upstash/redis";
const redis = Redis.fromEnv();
const index = await redis.search.createIndex({
name: "orders",
prefix: "order:",
dataType: "json",
schema: s.object({
product: s.string(),
category: s.facet(),
price: s.number("F64"),
quantity: s.number("U64"),
date: s.date(),
}),
});
// Insert sample data
await redis.json.set("order:1", "$", {
product: "Laptop",
category: "electronics",
price: 999.99,
quantity: 1,
date: "2024-06-15",
});
await redis.json.set("order:2", "$", {
product: "Mouse",
category: "electronics",
price: 29.99,
quantity: 3,
date: "2024-06-16",
});
await redis.json.set("order:3", "$", {
product: "Desk",
category: "furniture",
price: 249.99,
quantity: 1,
date: "2024-07-01",
});
await index.waitIndexing();
// Average price
const result = await index.aggregate({
aggregations: {
avg_price: { $avg: { field: "price" } },
},
});
// result.avg_price -> number
// Multiple metrics at once
const stats = await index.aggregate({
aggregations: {
avg_price: { $avg: { field: "price" } },
total_revenue: { $sum: { field: "price" } },
cheapest: { $min: { field: "price" } },
most_expensive: { $max: { field: "price" } },
order_count: { $count: { field: "price" } },
},
});
// Combined statistics
const priceStats = await index.aggregate({
aggregations: {
price_stats: { $stats: { field: "price" } },
// Returns: { count, min, max, sum, avg }
},
});
// Extended statistics (includes variance and standard deviation)
const extended = await index.aggregate({
aggregations: {
price_extended: { $extendedStats: { field: "price" } },
// Returns: { count, min, max, sum, avg, sumOfSquares, variance, stdDeviation }
},
});
// Percentiles
const percentiles = await index.aggregate({
aggregations: {
price_percentiles: { $percentiles: { field: "price", percents: [25, 50, 75, 95] } },
},
});
// Count distinct values
const uniqueCategories = await index.aggregate({
aggregations: {
unique_cats: { $cardinality: { field: "category" } },
},
});Bucket Aggregations
$terms - Group by field values
const byCategory = await index.aggregate({
aggregations: {
categories: {
$terms: { field: "category", size: 10 },
},
},
});
// categories.buckets -> [{ key: "electronics", doc_count: 2 }, { key: "furniture", doc_count: 1 }]$range - Group by numeric ranges
const priceRanges = await index.aggregate({
aggregations: {
price_ranges: {
$range: {
field: "price",
ranges: [
{ to: 50 }, // Under $50
{ from: 50, to: 200 }, // $50-$200
{ from: 200 }, // Over $200
],
},
},
},
});$histogram - Fixed-interval numeric buckets
const priceHistogram = await index.aggregate({
aggregations: {
price_distribution: {
$histogram: { field: "price", interval: 100 },
},
},
});$facet - Faceted navigation
const facets = await index.aggregate({
aggregations: {
brand_facets: { $facet: { field: "brand" } },
},
});Nested Aggregations
Combine buckets with metrics for multi-level analysis:
// Average price per category
const result = await index.aggregate({
aggregations: {
by_category: {
$terms: { field: "category" },
$aggs: {
avg_price: { $avg: { field: "price" } },
min_price: { $min: { field: "price" } },
max_price: { $max: { field: "price" } },
total_orders: { $count: { field: "price" } },
},
},
},
});
// by_category.buckets -> [
// { key: "electronics", doc_count: 2, avg_price: 514.99, min_price: 29.99, max_price: 999.99, total_orders: 2 },
// { key: "furniture", doc_count: 1, avg_price: 249.99, ... },
// ]Filtered Aggregations
Apply a filter before aggregating:
const electronicsStats = await index.aggregate({
filter: { category: { $eq: "electronics" } },
aggregations: {
avg_price: { $avg: { field: "price" } },
price_ranges: {
$range: {
field: "price",
ranges: [{ to: 100 }, { from: 100, to: 500 }, { from: 500 }],
},
},
},
});Available Aggregations
Metric Aggregations
| Aggregation | Description | | ---------------- | ------------------------------------------ | | `$avg` | Average value of a numeric field | | `$sum` | Sum of values | | `$min` | Minimum value | | `$max` | Maximum value | | `$count` | Count of documents | | `$cardinality` | Count of distinct values | | `$stats` | Combined count/min/max/sum/avg | | `$extendedStats` | Stats + variance/stdDeviation/sumOfSquares | | `$percentiles` | Percentile values at specified thresholds |
Bucket Aggregations
| Aggregation | Description | | ------------ | --------------------------------- | | `$terms` | Group by field values | | `$range` | Group by custom numeric ranges | | `$histogram` | Fixed-interval numeric buckets | | `$facet` | Faceted navigation (hierarchical) |
@upstash/redis is an HTTP/REST based Redis client for typescript, built on top of Upstash REST API. This project is in GA Stage. The Upstash Professional Support fully covers this project. It receives regular updates, and bug fixes.
Repo: upstash/redis-js
Other commands on redis-js.
- /aliases
Index aliases provide an indirection layer between your application and the actual index. You can point an alias to any index and swap it atomically, enabling zero-downtime reindexing.
Open command - /index-management
Create, inspect, and drop search indexes. Wait for indexing to complete after data changes. Indexes automatically track Redis keys matching a specified prefix.
Open command - /querying
Query documents from a search index using type-safe filters with support for pagination, sorting, field selection, scoring, and highlighting. Count matching documents efficiently without returning results.
Open command

