The $bucket stage groups documents into fixed numeric ranges you define—perfect for price tiers, age bands, score histograms, and any report where bucket edges are known in advance.
01
Range buckets
Define edges with boundaries.
02
groupBy field
Numeric expression per doc.
03
Custom output
count, avg, sum, $push.
04
default bucket
Catch outliers and nulls.
05
Histograms
One row per range band.
06
vs $bucketAuto
Fixed vs auto edges.
Fundamentals
Definition and Usage
$bucket is an aggregation stage that categorizes documents by a numeric groupBy value into predefined intervals. Instead of writing manual $switch or multiple $match stages, you list boundary numbers and MongoDB assigns each document to the correct bucket.
💡
Beginner tip
Each bucket’s _id in the output is the lower bound of that range (e.g. boundary 18 means “18 and up until the next boundary”). Think of it like chart bins on a histogram.
Use $bucket when business rules define the ranges—$0–$49, $50–$99, $100+. Use $bucketAuto when you want MongoDB to calculate evenly spaced edges from the data. Pair accumulators like $sum and $avg inside output.
Foundation
📝 Syntax
$bucket requires groupBy and boundaries; other fields customize behavior:
Place $match before $bucket to exclude documents you do not want counted. Here we skip the null-price gift card, then bucket on $score instead of price.
Same histogram logic
$bucket → fewer lines, clearer intent
$group + $switch → flexible but verbose
How It Works
When ranges are numeric and fixed, $bucket replaces boilerplate $switch logic. Use $group when _id is categorical (country, status) rather than numeric bins.
Compare
📋 $bucket vs related stages
Stage
Effect
Best for
$bucket
Group by fixed numeric boundaries you define
Known price tiers, age bands, SLA buckets
$bucketAuto
Auto-compute evenly spaced bucket edges
Exploratory histograms, unknown data spread
$group
Group by any _id expression
Categories, dates, compound keys
$facet
Run multiple sub-pipelines in parallel
Dashboard with several bucket views at once
$binSize (with $setWindowFields)
Window-based binning
Advanced analytics over ordered partitions
🧠 How $bucket Works
1
Evaluate groupBy
For each input document, MongoDB computes the groupBy expression (e.g. $price).
Input
2
Find matching bucket
Compare the value against boundaries. Assign to the interval or the default bucket if out of range.
Bin
3
Run accumulators
Update output fields for that bucket—$sum, $avg, $push, etc.
$bucket turns numeric fields into histogram-style summaries with minimal code. Define groupBy and boundaries, add output accumulators for richer stats, and set default for edge cases.
When bucket edges should come from the data itself, switch to $bucketAuto. When grouping is not range-based, use $group directly.
Always set default when null or out-of-range values are possible
Put $match before $bucket to reduce documents processed
Sort output by _id for charts that read left-to-right by range
Use meaningful boundary edges aligned to business rules (tax brackets, tiers)
Add a follow-up $addFields stage for human-readable bucket labels
❌ Don’t
Use $bucket for non-numeric categories—use $group instead
Forget that the last bucket has no upper cap unless you rely on default
Expect zero-count buckets to appear—they are skipped in output
Mix unsorted or duplicate boundary values
Confuse pipeline $bucket with unrelated “bucket” terms (S3, etc.)
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about $bucket
Use these points whenever you build range-based reports.
5
Core concepts
📊01
Fixed ranges
You define boundaries.
Basics
📈02
groupBy
Numeric expression.
Required
📦03
_id = lower bound
Bucket identifier.
Output
⚠️04
default bucket
Catch null/outliers.
Safety
🛠05
Custom output
avg, sum, push.
Stats
❓ Frequently Asked Questions
$bucket groups documents into fixed numeric ranges (buckets) based on a groupBy expression. You define boundary values; MongoDB assigns each document to the bucket whose range contains its groupBy value and returns one summary document per bucket.
groupBy (expression to bucket on, e.g. "$price") and boundaries (array of at least two ascending numbers that define bucket lower bounds). default is optional but recommended for null or out-of-range values. output is optional—if omitted, MongoDB adds count: { $sum: 1 }.
Each boundary is the inclusive lower bound of a bucket. A document with groupBy value v goes into the bucket where v >= boundary[i] and v < boundary[i+1]. The last bucket includes all values >= the last boundary. Boundaries must be sorted ascending.
Documents whose groupBy value is less than the first boundary, greater than or equal to the last boundary (when you want to cap ranges), null, or non-numeric (when boundaries are numeric) can land in the default bucket. Set default: "Other" or similar; that value becomes the bucket _id.
$bucket uses boundaries you specify—ideal for known ranges like age bands 0–18, 18–65. $bucketAuto computes bucket edges from the data (groupBy + buckets count). Use $bucket for fixed business rules; $bucketAuto for exploratory histograms.
Yes. The output object accepts any accumulator expressions—count with $sum, average with $avg, lists with $push, totals with $sum on a field path. Each bucket gets one aggregated result document.
Did you know?
$bucket and $bucketAuto were introduced in MongoDB 3.4 as dedicated histogram stages—before that, developers built the same logic with $group and $switch. See the official $bucket docs.