What is the aggregation $group stage and how does it work?
Learn how the MongoDB $group aggregation stage works: grouping keys, accumulators like $sum and $avg, grand totals with _id null, and real examples.
Expected Interview Answer
The $group stage in a MongoDB aggregation pipeline groups incoming documents by a key you specify in its _id field and computes aggregated values across each group using accumulator operators such as $sum, $avg, $min, $max, and $push. It is the pipeline equivalent of SQL's GROUP BY.
Each document flowing into $group is assigned to a bucket based on the _id expression — a single field, a computed value, or a composite object of several fields. Within each bucket, accumulators combine the grouped documents into one output document per distinct _id. Setting _id to null groups every document into a single bucket, which is how you compute grand totals. Because $group must see documents to bucket them, placing a $match before it reduces the working set and lets indexes filter early for better performance.
- Summarises many documents into per-group results
- Rich accumulators: $sum, $avg, $min, $max, $push, $addToSet
- Composite _id lets you group by multiple fields at once
- _id: null computes grand totals across the whole collection
- Composable with $match, $sort, and $project in one pipeline
AI Mentor Explanation
Think of a scorer tallying a team innings by batter. Every delivery is sorted into the bucket of the batter who faced it, and within each bucket the scorer sums runs and counts balls. $group does exactly this — the _id is the batter, and accumulators like $sum add up runs so you get one summary line per player from thousands of individual deliveries.
Step-by-Step Explanation
Step 1
Filter first
Place a $match before $group so indexes can shrink the input set and the pipeline processes fewer documents.
Step 2
Choose the group key
Set _id to the field or expression to group by; use an object like { region: '$region', year: '$year' } for multi-field grouping.
Step 3
Add accumulators
Define output fields using accumulators such as total: { $sum: '$amount' } or avg: { $avg: '$score' }.
Step 4
Grand totals
Set _id to null to fold every document into a single bucket and compute collection-wide aggregates.
Step 5
Shape the output
Follow with $sort to order groups and $project to rename or restructure fields for the final result.
Step 6
Mind memory limits
$group buffers group state; for very large groupings enable allowDiskUse so the stage can spill to disk.
What Interviewer Expects
- Knowing _id defines the grouping key
- Familiarity with accumulators like $sum, $avg, $push, $addToSet
- Understanding _id: null gives grand totals
- Placing $match before $group for performance
- Awareness of composite _id for multi-field grouping
Common Mistakes
- Omitting the _id field in the $group specification
- Referencing non-grouped fields directly without an accumulator
- Putting $group before $match and processing more documents than needed
- Confusing $push (keeps duplicates) with $addToSet (unique values)
- Forgetting allowDiskUse for very large grouping operations
Best Answer (HR Friendly)
“The $group stage bundles database records into groups based on a key you choose — like grouping sales by region — and then calculates summaries such as totals or averages for each group. It's MongoDB's way of doing what GROUP BY does in SQL, turning lots of raw records into a compact summary.”
Code Example
db.orders.aggregate([
{ $match: { status: 'paid' } },
{ $group: {
_id: '$region',
totalSales: { $sum: '$amount' },
orderCount: { $sum: 1 },
avgOrder: { $avg: '$amount' }
} },
{ $sort: { totalSales: -1 } }
]);db.orders.aggregate([
{ $group: {
_id: null,
grandTotal: { $sum: '$amount' },
documents: { $sum: 1 }
} }
]);db.orders.aggregate([
{ $group: {
_id: { region: '$region', year: '$year' },
productsSold: { $addToSet: '$product' },
revenue: { $sum: '$amount' }
} }
]);Follow-up Questions
- What is the difference between $push and $addToSet?
- Why should $match usually come before $group?
- How do you compute a grand total across all documents?
- How does $group compare to SQL GROUP BY?
- When would you need allowDiskUse with $group?
MCQ Practice
1. In a $group stage, what does the _id field specify?
The _id in $group defines the grouping key; documents sharing the same _id value are combined into one group.
2. How do you compute a single grand total across all documents with $group?
Setting _id to null places every document in one bucket, producing a single aggregated result.
3. Which accumulator collects only unique values into an array?
$addToSet accumulates distinct values, while $push keeps all values including duplicates.
Flash Cards
What does _id do in $group? — Defines the grouping key; documents with the same _id are combined into one group.
How to get a grand total? — Set _id to null so all documents fall into a single bucket.
$push vs $addToSet? — $push keeps all values (with duplicates); $addToSet keeps only unique values.
Why $match before $group? — It shrinks the input using indexes so $group processes fewer documents.
$group SQL equivalent? — GROUP BY with aggregate functions like SUM, AVG, MIN, MAX.
Continue Learning
Related Interview Questions
How does the $lookup stage perform joins in MongoDB aggregation?
medium
What is a compound index and how does the index prefix rule work?
medium
What is the difference between a covered query and a normal query in MongoDB?
medium
What is the difference between findOneAndUpdate and updateOne in MongoDB?
medium