Skip to content

Advanced Aggregation

$bucket and $bucketAuto

Group into ranges — histograms, price bands, age brackets — without a hand-rolled $cond.

AdvancedAbout 6 minutes

$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" }
      }
    }
  }
])
Catalogue in price bands. Upper bound is exclusive except the last.
{ _id: 0, count: 8, avgPrice: 420 }
{ _id: 1000, count: 15, avgPrice: 2800 }
{ _id: 5000, count: 10, avgPrice: 8900 }
{ _id: "other", count: 2, avgPrice: 25000 }
_id is the lower bound of the band. Keyboard at 4500 is in 1000.

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?

Think about it first.

Related lessons