Common aggregation mistakes
What makes these dangerous is that none of them throw. The pipeline runs, returns plausible-looking numbers, and the numbers are wrong.
Mistake 1: Forgetting $unwind
Question:
Revenue per product.
Data:
orders
→ items[]
You try grouping directly.
Ask:
Am I analyzing the order, or each item inside the order?
If each item:
Probably $unwind.
Mistake 2: $group too early
Imagine:
Need:
completed orders
Bad:
$group everything
↓
$match completed
Better:
$match completed
↓
$group
Reduce data early.
Mistake 3: Forgetting that $group changes the shape
Before:
{
_id: 1,
userId: 101,
status: "completed"
}
After:
{
$group: {
_id: "$userId",
count: { $sum: 1 }
}
}
You now have:
{
_id: 101,
count: 5
}
You no longer automatically have:
status
createdAt
items
Unless you explicitly preserve/accumulate them.
Mistake 4: Confusing $project and $group
$project
Transforms each document individually.
Document A → transformed A
Document B → transformed B
Whereas:
$group
Combines multiple documents.
A + B + C
↓
Grouped result
This distinction is fundamental.
Try it
The $group mistake, run rather than described:
db.orders.aggregate([
{
$group: {
_id: "$userId",
count: { $sum: 1 }
}
},
{ $limit: 3 }
])
Two fields. status, createdAt, items and rating all went in and none came out. Add status: { $first: "$status" } to the $group and it comes back - because you asked for it, which is the only way anything survives a $group.