Advanced Aggregation
$bucket and $bucketAuto
Group into ranges — histograms, price bands, age brackets — without a hand-rolled $cond.
$group by category is a discrete key. `$bucket` groups a numeric (or date) range. Price bands, age brackets, histograms. The alternative is $group plus a pile of $cond — that is the expressions module, and it is worse to read.
db.products.aggregate([
{
$bucket: {
groupBy: "$price",
boundaries: [0, 1000, 5000, 20000],
default: "other",
output: {
count: { $sum: 1 },
avgPrice: { $avg: "$price" }
}
}
}
]){ _id: 0, count: 8, avgPrice: 420 }
{ _id: 1000, count: 15, avgPrice: 2800 }
{ _id: 5000, count: 10, avgPrice: 8900 }
{ _id: "other", count: 2, avgPrice: 25000 }boundaries must be sorted, same type, at least two values. Documents outside the range go to default; omit default and those documents are dropped. $bucketAuto picks boundaries for you: { $bucketAuto: { groupBy: "$price", buckets: 4 } } — even-ish counts, not pretty round numbers. Use $bucket when the bands are a product decision (₹0–1k / 1k–5k). Use $bucketAuto when you want N groups and do not care where the cuts fall.
Interview question
When do you use $bucket instead of $group?
$group when the key is a field value — city, status, userId. $bucket when I am binning a number or date into ranges I define. Boundaries are inclusive on the lower end and exclusive on the upper, except the last. default catches outliers; without it they are dropped. $bucketAuto when I only care about N bins.