What is the MongoDB aggregation pipeline and how does it work?
Understand the MongoDB aggregation pipeline — stages like $match, $group, $lookup and $unwind — with real code and interview-ready explanations.
Expected Interview Answer
The MongoDB aggregation pipeline is a framework for processing data through an ordered sequence of stages, where each stage transforms the stream of documents and passes its output to the next, letting you filter, group, reshape, and compute results server-side.
Documents flow through stages like $match, $group, $project, $sort, $lookup, and $unwind, each performing one operation. It is analogous to Unix pipes: the output of one stage becomes the input of the next. The query optimizer can reorder and merge stages (for example pushing $match earlier so an index is used), and stages such as $group and $sort may spill to disk for large datasets when allowDiskUse is enabled.
- Performs complex transformations and analytics inside the database
- Composable stages make pipelines readable and reusable
- Can join collections with $lookup without application code
- Optimizer reorders stages and leverages indexes on early $match
- Reduces data transferred to the client by computing server-side
- Supports grouping, windowing, faceting, and reshaping in one query
AI Mentor Explanation
Think of a cricket analysis desk turning raw ball-by-ball data into a summary: first filter to one innings, then group balls by bowler, then compute economy rates, then sort by best figures. Each step feeds the next. The aggregation pipeline is that desk — ordered stages, each refining the stream of deliveries into the final scorecard insight.
Step-by-Step Explanation
Step 1
Filter early with $match
Put $match first to shrink the document stream and let the optimizer use an index before heavier stages run.
Step 2
Reshape or unwind
Use $project to select and compute fields, or $unwind to flatten array elements into separate documents.
Step 3
Group and aggregate
Use $group with accumulators like $sum, $avg, and $push to collapse documents into summarized results by a key.
Step 4
Join if needed
Use $lookup to pull related documents from another collection into each pipeline document.
Step 5
Sort, limit, and output
Finish with $sort, $limit/$skip for paging, and optionally $out or $merge to write results to a collection.
What Interviewer Expects
- Explains the pipeline as ordered, streaming stages like Unix pipes
- Names key stages and what each does ($match, $group, $project, $lookup, $unwind)
- Knows to place $match and $limit early for optimizer and index benefits
- Understands $group accumulators and _id as the grouping key
- Aware of allowDiskUse and stage memory limits for large datasets
Common Mistakes
- Placing $match after $group so no index can be used
- Confusing $project with $group
- Forgetting that _id in $group defines the grouping key, null groups everything
- Ignoring the per-stage memory limit and not enabling allowDiskUse
- Overusing $lookup on large collections without supporting indexes
Best Answer (HR Friendly)
“The aggregation pipeline is MongoDB's way of processing data in steps, like an assembly line: each stage does one job — filtering, grouping, or reshaping — and passes the result to the next. It lets you produce reports and summaries directly in the database instead of pulling everything into the application to compute.”
Code Example
db.orders.aggregate([
// 1. Filter early so an index on status/createdAt can be used
{ $match: { status: 'shipped', createdAt: { $gte: ISODate('2026-01-01') } } },
// 2. Group by month, summing amounts and counting orders
{ $group: {
_id: { month: { $month: '$createdAt' } },
totalRevenue: { $sum: '$amount' },
orderCount: { $sum: 1 },
avgOrder: { $avg: '$amount' }
} },
// 3. Reshape the output
{ $project: { _id: 0, month: '$_id.month', totalRevenue: 1, orderCount: 1, avgOrder: { $round: ['$avgOrder', 2] } } },
// 4. Sort by month
{ $sort: { month: 1 } }
], { allowDiskUse: true })db.orders.aggregate([
{ $lookup: {
from: 'customers',
localField: 'customerId',
foreignField: '_id',
as: 'customer'
} },
{ $unwind: '$customer' },
{ $project: { amount: 1, customerName: '$customer.name' } }
])Follow-up Questions
- Why should $match appear as early as possible in a pipeline?
- What is the difference between $project and $group?
- How does $lookup perform a join and what are its performance costs?
- What does allowDiskUse do and when is it needed?
- How does $unwind change the number of documents in the stream?
MCQ Practice
1. Which aggregation stage collapses documents into summarized results by a key?
$group buckets documents by its _id expression and applies accumulators like $sum and $avg to each bucket.
2. Where should $match ideally be placed for best performance?
An early $match reduces the document stream and can use an index before expensive stages run.
3. Which stage flattens an array field into multiple documents?
$unwind outputs one document per element of the specified array field.
Flash Cards
What does $match do? — Filters documents by a condition, ideally placed early so an index can be used.
What does the _id in $group define? — The grouping key; setting it to null groups all documents into one bucket.
What does $lookup do? — Performs a left outer join, pulling matching documents from another collection into an array field.
What is allowDiskUse? — An option letting blocking stages like $group and $sort spill to disk when they exceed the memory limit.