querydrill

Learn › Reference

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.

Other reference pages

MongoDB operator cheatsheet

How to think about an aggregation pipeline

$match vs $filter, $project vs $map, $group vs $reduce