MongoDB $sum Accumulator

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 5 Examples
Aggregation

What You’ll Learn

The $sum accumulator adds numeric values in each $group bucket—the workhorse for revenue totals, quantity rollups, point scores, and the classic $sum: 1 document count.

01

Total per group

Add numeric fields.

02

$sum: 1

Count documents.

03

Expressions OK

Sum computed values.

04

vs $avg

Total vs mean.

05

Null skipped

Non-numbers ignored.

06

Global total

_id: null pattern.

Definition and Usage

$sum is a MongoDB accumulator used in the $group stage. For each group, it evaluates an expression on every document and returns the arithmetic total of all numeric results.

💡
Beginner tip

Think of $sum as a running plus sign across the group. Sales of 120, 85, and 200 yield 405. Pass the literal 1 instead of a field path to count how many documents landed in each bucket.

Use $sum for order totals, inventory quantities, game points, and KPI rollups. Pair with $avg when you need both total and mean, or with $sum: 1 to show how many records contributed to each total.

📝 Syntax

$sum takes one expression inside $group:

mongosh
{
  $group: {
    _id: <expression>,
    <outputField>: { $sum: <expression> }
  }
}

Syntax Rules

  • Stage — primary use as accumulator in $group (also $bucket, windows).
  • Field sum{ $sum: "$amount" } adds the field value per document.
  • Document count{ $sum: 1 } adds 1 per document (row count).
  • Expression — any numeric formula, e.g. { $multiply: ["$price", "$qty"] }.
  • Non-numeric — null, missing, strings, and objects are skipped.
  • Empty numeric set — returns 0 when no numeric values contribute.
mongosh
db.orders.aggregate([
  {
    $group: {
      _id: "$storeId",
      totalSales: { $sum: "$amount" }
    }
  }
]);

⚡ Quick Reference

QuestionAnswer
Stage$group accumulator
Syntax{ $sum: <expression> }
Count docs{ $sum: 1 }
All non-numericReturns 0
vs $avg$sum = total; $avg = total ÷ count
Common pairing$match$group$sort
Field total
{ $sum: "$amount" }

Revenue per store

Doc count
{ $sum: 1 }

Orders per customer

Expression
{ $sum: {
  $multiply: ["$price", "$qty"]
} }

Line-item totals

Global
{ _id: null,
  total: { $sum: "$amount" } }

Grand total

🧰 Parameters

$sum accepts one expression inside $group:

expression Required

Numeric value added per document. Can be a field path, the literal 1 for counting, or a computed expression.

{ $sum: "$quantity" }
{ $sum: 1 }
_id Group key

Defines buckets. Use a field for per-category totals, compound keys for multi-field grouping, or null for one global bucket.

_id: "$storeId"
return type Number

Typically int, long, double, or Decimal128 depending on input types. Mixed numeric types follow MongoDB’s numeric promotion rules.

405
ignored inputs Important

Strings, booleans, arrays, objects, null, and missing fields do not add to the total. Filter with $match when data quality is uncertain.

$match: { amount: { $type: "number" } }

Examples Gallery

Sample order data—total sales per store, count orders, sum expressions, and compare with $avg.

📚 Getting Started

Insert sample orders and compute total sales per store.

Example 1 — Sample orders collection

mongosh
db.orders.insertMany([
  { orderId: "O1", storeId: "S1", amount: 120, quantity: 2 },
  { orderId: "O2", storeId: "S1", amount: 85,  quantity: 1 },
  { orderId: "O3", storeId: "S2", amount: 200, quantity: 4 },
  { orderId: "O4", storeId: "S2", amount: 50,  quantity: 1 },
  { orderId: "O5", storeId: "S1", amount: 95,  quantity: 3 }
]);

How It Works

Store S1 has three orders (120 + 85 + 95 = 300). Store S2 has two orders (200 + 50 = 250).

Example 2 — Total sales per store

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: "$storeId",
      totalSales: { $sum: "$amount" }
    }
  },
  { $sort: { totalSales: -1 } }
]);

/* Result:
[
  { _id: "S1", totalSales: 300 },
  { _id: "S2", totalSales: 250 }
]
*/

How It Works

Grouping by storeId creates one bucket per store. $sum adds every amount in that bucket.

📈 Practical Patterns

Count documents, sum expressions, and compare with averages.

Example 3 — Count orders with $sum: 1

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: "$storeId",
      orderCount: { $sum: 1 },
      totalSales: { $sum: "$amount" }
    }
  },
  { $sort: { _id: 1 } }
]);

/* S1 → orderCount: 3, totalSales: 300
   S2 → orderCount: 2, totalSales: 250 */
*/

How It Works

$sum: 1 is the idiomatic way to count documents per group—often paired with field sums in the same $group stage.

Example 4 — Sum total quantity per store

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: "$storeId",
      totalQty: { $sum: "$quantity" }
    }
  },
  { $sort: { _id: 1 } }
]);

/* S1 → totalQty: 6  (2+1+3)
   S2 → totalQty: 5  (4+1) */
*/

How It Works

You can sum any numeric field—or an expression like { $multiply: ["$price", "$quantity"] } for computed line totals.

Example 5 — $sum vs $avg

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: "$storeId",
      totalSales:   { $sum: "$amount" },
      avgOrderSize: { $avg: "$amount" },
      orderCount:   { $sum: 1 }
    }
  },
  { $match: { _id: "S1" } }
]);

/* S1:
   totalSales: 300
   avgOrderSize: 100   (300 / 3)
   orderCount: 3 */
*/

How It Works

$sum answers “how much in total?” $avg answers “what is the typical amount?” Use both when dashboards need revenue and average order value.

🧠 How $sum Works

1

Documents enter $group

MongoDB assigns each document to a bucket based on the _id expression.

Group
2

Evaluate expression

For each document, compute the $sum expression. Non-numeric results are skipped.

Eval
3

Running total updated

MongoDB adds each valid numeric value to the group’s accumulator (or adds 1 when using $sum: 1).

Add
=

Total returned

Each group outputs the final sum—or 0 if no numeric values contributed.

📝 Notes

  • $sum is an accumulator in $group—not a query filter operator.
  • $sum: 1 counts documents per group—the most common counting idiom in aggregation.
  • Null and missing values are ignored; they do not reduce the sum to zero mid-calculation.
  • If every value is non-numeric, result is 0 (unlike $avg which returns null).
  • Store amounts as numbers—not strings—or $sum will skip them silently.
  • Previous topic: $stdDevSamp. Next: $top.

Conclusion

$sum is the go-to MongoDB accumulator for additive totals: revenue per store, units shipped, points scored, and document counts via $sum: 1.

Filter with $match first, pair totals with $avg and counts for context, and use expressions when the value to add must be computed. Next: $top for ranked documents per group.

💡 Best Practices

✅ Do

  • Use $sum: 1 alongside field sums to show count and total together
  • Place $match before $group to sum only relevant documents
  • Validate numeric types in source data—strings are silently skipped
  • Use expressions for line totals: { $sum: { $multiply: […] } }
  • Sort by the sum field descending for top-N revenue reports

❌ Don’t

  • Use $sum when you need a mean—use $avg instead
  • Assume string amounts like "120" are summed—they are ignored
  • Confuse aggregation $sum with update operator $inc on single documents
  • Forget that _id: null still outputs _id: null in results
  • Compare totals across groups without also showing document counts

Key Takeaways

Knowledge Unlocked

Five things to remember about $sum

Use these points whenever you total numeric values in aggregation pipelines.

5
Core concepts
🔢 02

$sum: 1

Document count.

Pattern
📦 03

$group

Accumulator context.

Syntax
04

Skips non-numeric

Strings ignored.

Gotcha
📈 05

vs $avg

Total vs mean.

Compare

❓ Frequently Asked Questions

$sum adds numeric values across all documents in each $group bucket. It returns a running total—ideal for revenue, quantities, points, or any additive metric.
Inside $group: { totalAmount: { $sum: "$amount" } }. You can also pass the literal 1—{ count: { $sum: 1 } }—to count documents per group.
It adds 1 for every document in the group, producing a document count. This is the standard pattern for counting rows per bucket alongside other accumulators.
Null, missing fields, strings, and objects are ignored—they do not contribute to the total. If no numeric values exist, $sum returns 0 (unlike $avg which returns null).
$sum returns the total of numeric values. $avg divides that total by the count of numeric values. Use $sum for revenue totals; use $avg for per-unit means.
Yes. Pass any numeric expression: { $sum: { $multiply: ["$price", "$quantity"] } } totals line-item amounts per group.
Did you know?

You can manually compute $avg with $sum on a field and $sum: 1 for count, then divide in $project—but built-in $avg is clearer. The literal $sum: 1 pattern predates the dedicated $count stage and remains very common in tutorials and production pipelines. See the official $sum docs.

Continue the Accumulators Series

Total values with $sum, then learn $top for the highest-ranked document per group.

Next: $top →

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.

5 people found this page helpful