Home MongoDB Accumulators $sum MongoDB $sum Accumulator Definition
What Is $sum? $sum is a MongoDB accumulator for the $group stage. For each group it returns the total of numeric values from an expression.
$sum = add numeric values per group
{ $sum: "$amount" } → total of amount
{ $sum: 1 } → count documents in the group
null / missing / non-numeric → contribute 0
all non-numeric → 0
vs $avg → mean instead of total Use Prefer Total amount, quantity, revenue $sumAverage amount $avgCustom multi-step total $accumulator
Approach
How to Use $sum in MongoDB Pass a field, a constant, or any numeric expression.
Put $sum inside $group on an output field. Pass "$amount" to total a field, or 1 to count documents. Set _id to the group key, or null for one overall total. Optionally $match first so you sum only the rows you care about. Piece Required? Role $group._idYes Group key ("$category", null, …) $sumYes Expression or constant to add Common forms — "$field", 1, or { $multiply: [...] }
Pseudocode for each group:
total = 0
for each document in group:
value = evaluate(expression)
if value is numeric:
total = total + value
// else: add 0
emit { _id: groupKey, field: total } Reference
Cheat Sheet Keep these facts handy while writing a total.
Topic Detail Stage $group accumulator (also usable in $project)Syntax { $sum: "$field" } or { $sum: 1 }null / missing Contribute 0 to the total Count docs { $sum: 1 }vs $avg Total vs mean Sample check 100 + 150 + 200 + 50 = 500
Try it
Live Preview Watch the running total update. Sample collection: food 100, food 150, travel 200, food 50.
Trace
Worked Walkthrough — Overall Total Same four purchases as the examples. Watch the total grow from 0 to 500.
Documents:
{ amount: 100, category: "food" }
{ amount: 150, category: "food" }
{ amount: 200, category: "travel" }
{ amount: 50, category: "food" }
All docs (_id: null):
100 + 150 + 200 + 50 = 500
Food only:
100 + 150 + 50 = 300
Travel only:
200
Output (all docs):
{ _id: null, totalAmount: 500 } Code
MongoDB Examples We use a tiny shopping list of four purchases. First we total every amount. Then we total per category. Finally we count documents with $sum: 1. Run these in mongosh after inserting the sample data once.
1. Sample data 2. Overall total 3. Total per category 4. Count with $sum: 1 Example 1 — Sample Data Imagine four receipts in a transactions collection. Each document has an amount and a category.
db.transactions.insertMany([
{ amount: 100, category: "food" },
{ amount: 150, category: "food" },
{ amount: 200, category: "travel" },
{ amount: 50, category: "food" }
]); How the Data Is Stored in MongoDB After the insert, MongoDB keeps 4 documents in transactions. Run find() to see them:
[
{ amount: 100, category: "food" },
{ amount: 150, category: "food" },
{ amount: 200, category: "travel" },
{ amount: 50, category: "food" }
] Read each document like this:
Field in MongoDB Meaning Example amountMoney spent on this purchase 100categoryWhat the purchase was for "food"
Four purchases:
food 100
food 150
travel 200
food 50
Next: $sum amounts → 500 How It Works Insert once. The sample command adds 4 documents to transactions.MongoDB stores fields as written. Each document keeps the same field names and values you inserted.find() shows the same shape. What you inserted is what you get back—ready for $sum in the next examples.Quick math: all amounts 100 + 150 + 200 + 50 = 500; food only 300; travel 200.
Example 2 — Overall Total Goal: one total for the whole collection. _id: null means “put every document in one big group.”
db.transactions.aggregate([
{
$group: {
// null = one group for the whole collection
_id: null,
totalAmount: { $sum: "$amount" }
}
}
]); [ { _id: null, totalAmount: 500 } ] How It Works One bucket. _id: null groups every document together.Read each amount. $sum: "$amount" pulls the numeric field from each receipt.Add them up. 100 + 150 + 200 + 50 = 500.Need the mean instead? Use { $avg: "$amount" } (result would be 125).Example 3 — Total per Category Goal: total spend for food and for travel. _id: "$category" makes a separate group for each category value.
Category Amounts Total food100, 150, 50 300 travel200 200
db.transactions.aggregate([
{
$group: {
_id: "$category",
totalAmount: { $sum: "$amount" }
}
},
{ $sort: { _id: 1 } }
]); [
{ _id: "food", totalAmount: 300 },
{ _id: "travel", totalAmount: 200 }
] How It Works Split into buckets. _id: "$category" creates separate groups for food and travel.Sum inside each bucket. Food: 300. Travel: 200.Sort for stable reading. $sort orders the group keys alphabetically.Same operator, different key. Only _id changed from Example 2.Example 4 — Count Documents with $sum: 1 Goal: how many receipts per category. { $sum: 1 } adds one for every document—a simple document count.
db.transactions.aggregate([
{
$group: {
_id: "$category",
orderCount: { $sum: 1 },
totalAmount: { $sum: "$amount" }
}
},
{ $sort: { _id: 1 } }
]); [
{ _id: "food", orderCount: 3, totalAmount: 300 },
{ _id: "travel", orderCount: 1, totalAmount: 200 }
] How It Works Same groups. Still one bucket per category.Add 1 per document. Food has three receipts → orderCount: 3.Total alongside count. You can use two $sum fields in the same $group.Why not always $count? The $count stage counts the whole pipeline result. Inside $group, { $sum: 1 } is the usual per-bucket count. Edge Cases & Pitfalls Check these before shipping a totals report.
null Null and missing add nothing They contribute 0. An empty numeric set still yields 0, not null.
types Strings are not added A string like "100" is ignored. Convert with $toDouble / $convert before summing if needed.
avg Do not confuse with $avg $sum answers “how much in total?” $avg answers “how much on average?”
count $sum: 1 counts documents Use it inside $group for per-bucket counts. It is not the same as summing a field named 1.
Analysis
Performance Notes Approach Cost Best for $sumNative, one pass per group Totals and document counts $avgSimilar native cost Means over numeric fields $accumulatorJS per document Custom rollups only
Prefer native $sum over a custom JavaScript reducer for plain totals. Filter early with $match so fewer documents enter the group.
Remember
Key Takeaways Role: numeric total inside $group.
Count: { $sum: 1 } counts documents per group.
Nulls: contribute 0; empty numeric set returns 0.
vs $avg: total for sums; mean for averages.
One line: $sum is the built-in adder for each $group bucket—totals fields or counts docs with 1.
Frequently Asked Questions What does MongoDB $sum do? $sum totals numeric values of an expression across all documents in each $group bucket. Non-numeric values are ignored (treated as zero contribution).
Where do I use $sum? Inside $group: { total: { $sum: "$amount" } }. It also works as an expression in $project. This page focuses on the $group accumulator.
What does $sum: 1 mean? { $sum: 1 } adds 1 for every document in the group, so the result is a document count. It is a common way to count rows per group.
How does $sum treat null or missing fields? Null and missing values do not change the total (they contribute 0). If every value is non-numeric, $sum returns 0.
How is $sum different from $avg? $sum returns a total. $avg returns the mean (total ÷ count of numerics). Use $sum for revenue; use $avg for average order size.
Can I sum an expression? Yes. Pass any numeric expression, for example { $sum: { $multiply: ["$price", "$qty"] } } to total line amounts.
About the author Developer, cloud engineer, and technical writer
I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.
9 people found this page helpful
Helpful Share Copy link Suggestion