Pipeline mental model (stages flow) in MongoDB - Time & Space Complexity
When using a MongoDB pipeline, we want to know how the time it takes grows as we add more data or stages.
We ask: How does the pipeline's work increase when the input or steps grow?
Analyze the time complexity of the following MongoDB aggregation pipeline.
db.orders.aggregate([
{ $match: { status: "shipped" } },
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 5 }
])
This pipeline filters shipped orders, groups by customer to sum amounts, sorts totals descending, and limits to top 5.
Look for repeated work inside the pipeline.
- Primary operation: Scanning all documents to filter and group.
- How many times: Each document is processed once through each stage in order.
As the number of orders grows, the pipeline must check and group more documents.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 document checks and groupings |
| 100 | About 100 document checks and groupings |
| 1000 | About 1000 document checks and groupings |
Pattern observation: The work grows roughly in direct proportion to the number of documents.
Time Complexity: O(n log n)
This means the pipeline's work grows roughly linearly with the number of input documents, but sorting adds a logarithmic factor.
[X] Wrong: "Adding more stages always multiplies the time by the number of stages."
[OK] Correct: Each document passes through stages one after another, so time grows mostly with input size, not simply by multiplying stages.
Understanding how pipeline stages process data step-by-step helps you explain performance clearly and shows you know how MongoDB handles data flow.
"What if we added a $lookup stage that joins with another collection? How would the time complexity change?"
Practice
Solution
Step 1: Understand the pipeline concept
Each stage in a pipeline processes data step-by-step, modifying or filtering it.Step 2: Identify the role of stages
Stages do not create databases or delete collections; they only transform or filter data.Final Answer:
Transforms or filters data before passing it to the next stage -> Option CQuick Check:
Pipeline stages transform or filter data [OK]
- Thinking stages create or delete collections
- Confusing pipeline with database commands
- Assuming stages run SQL queries
Solution
Step 1: Identify aggregation pipeline syntax
The aggregation pipeline uses the aggregate() method with an array of stages.Step 2: Compare options
Only db.collection.aggregate([ { $match: { status: 'A' } } ]) uses aggregate() with a pipeline stage ($match). Others use find, insert, or update incorrectly.Final Answer:
db.collection.aggregate([ { $match: { status: 'A' } } ]) -> Option DQuick Check:
aggregate() starts pipelines [OK]
- Using find() instead of aggregate() for pipelines
- Trying to insert pipeline stages
- Using update() with pipeline syntax
[{ $match: { age: { $gte: 18 } } }, { $group: { _id: '$city', count: { $sum: 1 } } }], what does the output represent?Solution
Step 1: Analyze the $match stage
This stage filters documents where age is 18 or more.Step 2: Analyze the $group stage
Groups filtered documents by city and counts how many per city.Final Answer:
Count of people grouped by city who are 18 or older -> Option AQuick Check:
$match filters, $group counts by city [OK]
- Confusing $sum with sum of ages
- Ignoring the filter condition
- Assuming output lists all people
[{ $match: { score: { $gt: 50 } } }, { $project: { score: 1, name: 1 } }, { $match: { name: 'Alice' } }]Solution
Step 1: Check multiple $match stages
MongoDB allows multiple $match stages anywhere in the pipeline.Step 2: Check $project usage
$project can select fields; _id is included by default unless excluded explicitly.Final Answer:
The pipeline syntax is correct and will work as expected -> Option BQuick Check:
Multiple $match and $project usage is valid [OK]
- Thinking multiple $match stages are invalid
- Assuming _id must be included explicitly
- Believing $project must come last
Solution
Step 1: Filter products with stock > 0 first
The $match stage must come first to filter only products in stock.Step 2: Group by category and calculate average price
Use $group with _id as category and $avg on price to get average price per category.Final Answer:
[{ $match: { stock: { $gt: 0 } } }, { $group: { _id: '$category', avgPrice: { $avg: '$price' } } }] -> Option AQuick Check:
Filter then group for correct average [OK]
- Grouping before filtering causes wrong results
- Averaging wrong fields
- Filtering on price instead of stock
Ready to prove it?
Pass the test and this pattern moves unknown
