MongoDB Accumulators

Beginner
10 min read
Updated: Oct 2026
Entry guide
Live examples

What Are MongoDB Accumulators?

MongoDB accumulators are operators that compute one result per group. They live mainly inside the $group stage and roll many documents into totals, averages, arrays, or ranked picks.

You use accumulators to sum, average, collect, rank, and merge values across documents that share the same group key. Expression operators (like $add) work on one document at a time; accumulators work across a whole bucket.

Remember
Accumulator = rollup inside $group

Examples:
  $sum      → total (or count with $sum: 1)
  $avg      → mean of numeric values
  $push     → collect every value into an array
  $topN     → top N ranked documents per group

Browse every tutorial in the left sidebar.

How MongoDB Accumulators Work

Documents enter $group. MongoDB puts each document into a bucket based on _id. Every accumulator field updates its state for that bucket, then emits one value when the group finishes.

  1. Optionally filter first with $match.
  2. Choose a group key for _id (field, compound object, or null).
  3. Add accumulator fields ($sum, $avg, …).
  4. Each group emits one document with those computed fields.
PieceRole
_idDefines the group bucket (field, object, or null)
Accumulator fieldOne output value (or array) per bucket
Field path"$amount" reads the current document’s field
Input orderMatters for $first / $last—sort first when needed
mongosh
// Total + count per store
db.orders.aggregate([
  {
    $group: {
      _id: "$storeId",
      revenue: { $sum: "$amount" },
      orders:  { $sum: 1 }
    }
  }
])

// Global average (one bucket)
db.orders.aggregate([
  { $group: { _id: null, avgAmount: { $avg: "$amount" } } }
])

How It Works

  1. Bucket by store. _id: "$storeId" creates one group per store.
  2. $sum: adds amount; $sum: 1 counts documents.
  3. Global group. _id: null puts every document in one bucket for a single average.

MongoDB Accumulator Syntax

Accumulators appear as fields inside $group. The pattern is always: output field name → { $accumulator: <input> }.

Pattern
{
  $group: {
    _id: <group key>,
    <outputField>: { $accumulatorName: <expression> }
  }
}

"$fieldName"  → value from the current document
$sum: 1       → count documents in the group

$sum

Add numeric values in the group

{ $sum: "$amount" }

$avg

Mean of numeric values

{ $avg: "$score" }

$push

Collect every value into an array

{ $push: "$name" }

$topN

Top N ranked documents (5.2+)

{ $topN: { n: 3, sortBy: { score: -1 }, output: "$$ROOT" } }

Tip: some names also exist as expression operators (for example $sum in $group vs expression form). Context decides which syntax MongoDB expects—check the individual tutorial when unsure.

Pseudocode

Use this mental model before you write a $group stage.

Pseudocode
goal = what you need per group (total / mean / list / top record)

buckets = empty map

for each document:
    key = evaluate(_id expression)
    put document into buckets[key]
    update each accumulator state for that key

for each key in buckets:
    emit {
      _id: key,
      field1: finalize(accumulator1),
      field2: finalize(accumulator2),
      ...
    }

How It Works

  1. Start from the business question (total sales? unique tags? top 3?).
  2. Pick the accumulator family that answers that question.
  3. Group documents, update state per document, then emit one result per bucket.

Accumulator Categories

Major families below. The left sidebar lists every tutorial—this section only explains when each family is useful.

CategoryUsed forExamples
NumericTotals, means, extremes, spread$sum, $avg, $min, $max
Arrays & objectsCollect values or merge documents$push, $addToSet, $mergeObjects
First / lastValues based on input stream order$first, $last, $firstN
RankingBest / worst documents with sortBy (5.2+)$top, $topN, $bottom
N-variantsArrays of N extremes or ordered values (5.2+)$minN, $maxN, $lastN
StatisticsStandard deviation of numeric fields$stdDevPop, $stdDevSamp
CustomJavaScript when built-ins cannot express the rule$accumulator

For per-document math and conditionals, see the operators hub. For pipeline steps around $group, see aggregation stages.

Common MongoDB Accumulators

A short starter set. Open any name for a full tutorial; use the sidebar for the complete catalog.

AccumulatorQuick meaning
$sumTotal values, or count with $sum: 1
$avgArithmetic mean of numbers
$min / $maxSmallest / largest value in the group
$pushCollect every value (duplicates kept)
$addToSetCollect unique values only
$first / $lastFirst / last value seen (order-sensitive)
$top / $topNBest document(s) by sortBy (5.2+)
$mergeObjectsShallow-merge objects in the group

Worked Example

Small orders collection. We keep completed orders, then compute count, revenue, average, and unique customers per store.

Example 1 — Sample Data

Four orders across two stores.

mongosh
db.orders.insertMany([
  { _id: 1, storeId: "A", customerId: "c1", amount: 40, status: "completed" },
  { _id: 2, storeId: "A", customerId: "c2", amount: 60, status: "completed" },
  { _id: 3, storeId: "B", customerId: "c1", amount: 25, status: "completed" },
  { _id: 4, storeId: "A", customerId: "c2", amount: 15, status: "cancelled" }
]);

How It Works

  1. Insert four documents into orders.
  2. Store A has two completed orders and one cancelled.
  3. Store B has one completed order.

Example 2 — Multi-Accumulator $group

Filter to completed orders, then roll up several metrics per store in one stage.

mongosh
db.orders.aggregate([
  { $match: { status: "completed" } },
  {
    $group: {
      _id: "$storeId",
      orderCount: { $sum: 1 },
      revenue:    { $sum: "$amount" },
      avgOrder:   { $avg: "$amount" },
      customers:  { $addToSet: "$customerId" }
    }
  },
  { $sort: { revenue: -1 } }
]);

How It Works

  1. $match. Drops the cancelled order (_id: 4).
  2. $group by store. Creates buckets "A" and "B".
  3. $sum. Counts documents and totals amount (A: 40+60=100).
  4. $avg. Mean order size for A is 100 / 2 = 50.
  5. $addToSet. Unique customer ids per store (order not guaranteed).

Choosing the Right Accumulator

Match the business question to the family first; then pick a specific operator.

If you need to…Start with
Total revenue or quantity$sum (use $sum: 1 to count)
Average score or price$avg
Every value in a list$push
Unique tags or ids$addToSet
Best / worst full record$top / $bottom (5.2+)
Top-N leaderboard per group$topN
Custom business rule$accumulator only when built-ins fall short

Edge Cases & Pitfalls

Common beginner traps when learning MongoDB accumulators.

order

$first / $last need stable order

Without a prior $sort, first/last follow stream order and can surprise you. For ranked picks, prefer $top / $topN.

types

String amounts are skipped

Store numbers as numeric BSON types. Values like "120" are ignored by $sum and $avg—convert first if needed.

null

Null and missing fields

Missing or null inputs are often ignored by numeric accumulators. An empty numeric group can yield null for $avg.

memory

$push can grow large

Huge groups with $push can hit the 100 MB per-group limit. Filter with $match earlier or reshape in stages.

context

Accumulator vs expression

{ total: { $sum: "$amount" } } inside $group is an accumulator. Per-document math belongs in $project / $addFields with expression operators.

version

Ranking needs MongoDB 5.2+

$top, $bottom, $topN, $bottomN, and several N-variants require MongoDB 5.2 or later. Check your server version before relying on them.

Performance Notes

IdeaPractical tip
Accumulators are not “slow by default”Cost comes from how many documents enter each group and what you collect
Filter earlyPlace $match before $group to shrink work
Indexes help the filterIndex fields used in early $match / sort stages when possible
Prefer built-ins$sum / $avg beat custom $accumulator for standard rollups
Watch large arraysAvoid unbounded $push on huge groups; project only needed fields

Use explain() when a pipeline feels slow. Prefer selective filters and smaller working sets over micro-optimizing a single accumulator choice.

Key Takeaways

  • Accumulators compute one value per $group bucket.
  • Combine freely: one $group can run many accumulators together.
  • Learn families, then open individual tutorials from the left sidebar.
  • Filter early and watch types, nulls, and order-sensitive operators.

One line: Accumulators answer “what is true for this whole group?”—totals, means, lists, and rankings inside $group.

Frequently Asked Questions

Accumulators are operators used mainly inside $group to compute one output value per group bucket—totals, averages, arrays, ranked documents, or custom JavaScript rollups.
Primarily in $group: { _id: "$category", total: { $sum: "$amount" } }. Each accumulator processes every document that falls into the same _id bucket.
Accumulators aggregate across many documents in a group. Expression operators like $add or $cond run per document inside $project or $addFields. Some names (for example $sum) exist in both forms with different syntax.
The leading $ marks a reserved operator name so MongoDB can tell accumulators apart from ordinary field names in the $group stage.
Yes. One $group can run $sum, $avg, $push, and others together. Each output field keeps its own independent state per bucket.
Use the left sidebar on this section to open each tutorial under /mongodb/accumulators/<name>. This page is the overview; individual pages cover syntax, examples, and pitfalls in depth.
Core operators ($sum, $avg, $push, $addToSet, $min, $max, $first, $last) are widely available. $top, $bottom, $topN, $bottomN, $firstN, $lastN, $minN, and $maxN require MongoDB 5.2 or later.

Next: $accumulator

Custom JavaScript rollups when built-in accumulators are not enough.

$accumulator tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

11 people found this page helpful