0
0
MongodbHow-ToBeginner · 2 min read

MongoDB Query to Find Total Per Group Using Aggregation

Use the MongoDB aggregation pipeline with $group stage to find totals per group, for example: db.collection.aggregate([{ $group: { _id: "$groupField", total: { $sum: "$valueField" } } }]).
📋

Examples

Input[{ category: "fruit", quantity: 10 }, { category: "vegetable", quantity: 5 }, { category: "fruit", quantity: 15 }]
Output[{ _id: "fruit", total: 25 }, { _id: "vegetable", total: 5 }]
Input[{ type: "A", amount: 100 }, { type: "B", amount: 200 }, { type: "A", amount: 50 }, { type: "B", amount: 150 }]
Output[{ _id: "A", total: 150 }, { _id: "B", total: 350 }]
Input[]
Output[]
🧠

How to Think About It

To find totals per group in MongoDB, think of grouping documents by a field using $group and then summing the values of another field within each group using $sum. This aggregates data by categories or types, similar to summing expenses by month in a spreadsheet.
📐

Algorithm

1
Identify the field to group by (e.g., category or type).
2
Identify the numeric field to sum (e.g., quantity or amount).
3
Use the aggregation pipeline with a <code>$group</code> stage.
4
Set <code>_id</code> to the group field to group documents.
5
Use <code>$sum</code> to add up the values in each group.
6
Return the grouped totals.
💻

Code

mongodb
db.collection.aggregate([
  { $group: { _id: "$category", total: { $sum: "$quantity" } } }
])
Output
[ { "_id": "fruit", "total": 25 }, { "_id": "vegetable", "total": 5 } ]
🔍

Dry Run

Let's trace the aggregation on example documents grouped by 'category' and summed by 'quantity'.

1

Group documents by category

Documents: [{category: 'fruit', quantity: 10}, {category: 'vegetable', quantity: 5}, {category: 'fruit', quantity: 15}]

2

Sum quantity values per group

fruit: 10 + 15 = 25, vegetable: 5

3

Return grouped totals

[{_id: 'fruit', total: 25}, {_id: 'vegetable', total: 5}]

CategoryQuantityRunning Total
fruit1010
vegetable55
fruit1525
💡

Why This Works

Step 1: Grouping documents

The $group stage groups documents by the specified field, here category, creating buckets for each unique value.

Step 2: Summing values

Within each group, $sum adds up the values of the quantity field to get the total per group.

Step 3: Output format

The result documents have _id as the group key and total as the sum, showing totals per group.

🔄

Alternative Approaches

Using $group with $addToSet for unique counts
mongodb
db.collection.aggregate([
  { $group: { _id: "$category", uniqueQuantities: { $addToSet: "$quantity" } } }
])
This groups by category but collects unique quantity values instead of summing; useful for distinct counts.
Using map-reduce (legacy approach)
mongodb
db.collection.mapReduce(
  function() { emit(this.category, this.quantity); },
  function(key, values) { return Array.sum(values); },
  { out: "totals_per_category" }
)
Map-reduce can do grouping and summing but is slower and more complex than aggregation.

Complexity: O(n) time, O(k) space

Time Complexity

The aggregation scans all n documents once, grouping them by k unique keys, so time is O(n).

Space Complexity

Space depends on the number of groups k, as it stores totals per group, so O(k).

Which Approach is Fastest?

The aggregation pipeline with $group is faster and more efficient than map-reduce for this task.

ApproachTimeSpaceBest For
Aggregation with $groupO(n)O(k)Fast grouping and summing
Map-ReduceO(n)O(k)Complex custom aggregation, slower
$group with $addToSetO(n)O(k)Unique value collection, not sum
💡
Always use the aggregation framework with $group and $sum for efficient grouping and totaling in MongoDB.
⚠️
Forgetting to prefix field names with "$" inside $group expressions causes errors or wrong results.