MongoDB Accumulators

What you’ll learn
- What MongoDB accumulators are and how they fit inside
$group. - Which operator to pick for totals, arrays, ranked records, and custom logic.
- A suggested learning path from
$sumthrough$topN. - How to combine multiple accumulators in one grouping stage.
- Links to every accumulator tutorial on CodeToFun (20 operators).
Prerequisites
Basic familiarity with MongoDB collections, the aggregation framework, and the $group stage. Helpful background: $match to filter before grouping and $sort when order affects $first / $last results.
$groupbasics: the_idexpression defines buckets; other fields use accumulators.- Field paths:
"$amount"refers to the current document’s field inside accumulators. - mongosh: run pipelines in the shell or Compass aggregation tab to verify output.
- MongoDB 5.2+ for ranked accumulators (
$top,$bottomN, etc.).
Key concepts
Every accumulator follows the same mental model: documents enter a group bucket, the operator updates state for each document, and one value is emitted per group.
Group buckets
_id can be a field, compound object, or null for one global group.
One output per group
Each accumulator field produces a single value (or array) per _id bucket.
Combine freely
One $group can run $sum, $avg, and $push together.
Filter first
Place $match before $group to shrink data and speed up aggregation.
Overview
Accumulators power analytics in MongoDB: revenue by store, average rating by product, unique tags per article, or the top three scores per class. Built-in operators cover most reports; $accumulator handles bespoke JavaScript when needed.
Numeric rollups
$sum, $avg, $min, $max, standard deviation.
Arrays & objects
$push, $addToSet, $mergeObjects.
Ranking
$top, $topN, $bottom, $bottomN with sortBy.
⚖️ Picking the right accumulator
Match the business question to the operator family before writing a pipeline.
| Goal | Start with | Notes |
|---|---|---|
| Total revenue or quantity | $sum | Use { $sum: 1 } to count documents per group. |
| Average score or price | $avg | Ignores non-numeric values; returns null if none. |
| Every value in a list | $push | Keeps duplicates and order (within group processing). |
| Unique tags or ids | $addToSet | Skips duplicates; order not guaranteed. |
| Best / worst full record | $top / $bottom | Requires sortBy; MongoDB 5.2+. |
| Top 3 leaderboard per group | $topN | Returns an array of up to N documents. |
| Custom business rule | $accumulator | JavaScript; use only when built-ins fall short. |
Multiple accumulators in one $group
A typical dashboard bucket: count orders, total revenue, average order size, and collect unique customer ids—all in one stage.
db.orders.aggregate([
{ $match: { status: "completed" } },
{
$group: {
_id: "$storeId",
orderCount: { $sum: 1 },
revenue: { $sum: "$amount" },
avgOrder: { $avg: "$amount" },
customers: { $addToSet: "$customerId" }
}
},
{ $sort: { revenue: -1 } }
]); Suggested learning path
Work through tutorials in this order if you are new to MongoDB aggregation accumulators.
- Custom escape hatch:
$accumulator— understand when JavaScript is needed. - Arrays:
$addToSetand$pushfor collecting values. - Numeric core:
$avg,$sum,$min,$max. - Order:
$first/$lastand N-variant pages with$sort. - Ranking:
$top,$topN,$bottomN. - Advanced numeric:
$stdDevSampand$mergeObjects.
Accumulator index
Every tutorial lives at /mongodb/accumulators/{slug}. Multi-word operators use kebab-case slugs (for example add-to-set, std-dev-pop).
Custom
| Operator | What it does |
|---|---|
$accumulator | Custom JavaScript with init, accumulate, merge, and finalize. |
Numeric
| Operator | What it does |
|---|---|
$sum | Add numeric values or count documents with $sum: 1 per group. |
$avg | Arithmetic mean of numeric field values in each bucket. |
$min | Smallest value of a single field across the group. |
$max | Largest value of a single field across the group. |
$minN | Array of the N smallest numeric values (MongoDB 5.2+). |
$maxN | Array of the N largest numeric values (MongoDB 5.2+). |
$stdDevPop | Population standard deviation (divide by N). |
$stdDevSamp | Sample standard deviation (divide by N − 1). |
Arrays & objects
| Operator | What it does |
|---|---|
$push | Append every value into an array (duplicates allowed). |
$addToSet | Collect unique values into an array per group. |
$mergeObjects | Shallow-merge document objects; last duplicate key wins. |
First / last (input order)
| Operator | What it does |
|---|---|
$first | First value seen in the group (depends on input order). |
$firstN | First N values as an array (use $sort first for ranked results). |
$last | Last value seen in the group. |
$lastN | Last N values as an array. |
Ranking (sortBy)
Pitfalls to avoid
Unstable without $sort
$first and $last follow ingestion order unless you sort the stream first. For ranked results use $top / $topN.
String amounts skipped
Store numbers as numeric BSON types. String values like "120" are ignored by $sum and $avg.
Memory growth
Large groups with $push can hit the 100 MB per-group limit. Filter with $match or aggregate in stages.
❓ FAQ
Summary
- Scope: 20 accumulator tutorials covering numeric, array, ranking, and custom operators.
- Pattern: accumulators live inside
$groupand emit one value per bucket. - Next step: open MongoDB $accumulator Operator or pick any row from the index above.
The same aggregation stage can mix many accumulators—$sum, $avg, and $addToSet in one $group—because each output field maintains its own independent state per bucket. See the official $group accumulators list.
9 people found this page helpful
