$project stage for shaping output in MongoDB - Time & Space Complexity
We want to understand how the time it takes to shape data with the $project stage changes as the data grows.
How does the work grow when we change the number of documents?
Analyze the time complexity of the following code snippet.
db.collection.aggregate([
{ $project: {
name: 1,
age: 1,
isAdult: { $gte: ["$age", 18] }
}}
])
This code shapes each document to only include name, age, and a new field isAdult based on age.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Processing each document once to reshape fields.
- How many times: Once per document in the input collection.
As the number of documents grows, the work grows directly with it because each document is processed once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 operations (one per document) |
| 100 | 100 operations |
| 1000 | 1000 operations |
Pattern observation: The work increases in a straight line as the number of documents increases.
Time Complexity: O(n)
This means the time to reshape the data grows directly with the number of documents.
[X] Wrong: "The $project stage processes only a few documents quickly, so it runs in constant time regardless of data size."
[OK] Correct: Actually, $project touches every document once, so the time grows as the number of documents grows.
Understanding how $project scales helps you explain how data shaping affects performance in real projects.
What if we added a $match stage before $project to filter documents? How would the time complexity change?
Practice
$project stage do in a MongoDB aggregation pipeline?Solution
Step 1: Understand the purpose of
The$project$projectstage is used to control which fields appear in the output documents and how they are shaped.Step 2: Compare with other stages
Filtering is done by$match, sorting by$sort, and grouping by$group. So$projectis for shaping output fields.Final Answer:
It shapes the output by selecting, renaming, or creating fields. -> Option BQuick Check:
$projectshapes output = A [OK]
- Confusing $project with $match for filtering
- Thinking $project sorts documents
- Mixing $project with $group for aggregation
name and age fields in the output using $project?Solution
Step 1: Recall
To include fields, set them to 1. To exclude, set to 0. Boolean or strings are invalid.$projectsyntax for inclusionStep 2: Check each option
{ $project: { name: 1, age: 1 } } uses 1 for inclusion correctly. { $project: { name: 0, age: 0 } } excludes fields. { $project: { name: true, age: true } } uses true which is invalid. { $project: { name: 'include', age: 'include' } } uses strings which is invalid.Final Answer:
{ $project: { name: 1, age: 1 } } -> Option AQuick Check:
Include fields = 1 in $project [OK]
- Using true/false instead of 1/0
- Mixing inclusion and exclusion in same $project
- Using strings instead of numbers for field selection
{ "name": "Alice", "age": 25, "city": "NY" }What will be the output of this aggregation?
[{ $project: { fullName: "$name", ageInMonths: { $multiply: ["$age", 12] }, _id: 0 } }]Solution
Step 1: Understand field renaming and calculation
ThefullNamefield is created by copyingname. TheageInMonthsis calculated by multiplyingageby 12 (25*12=300). The_idis excluded.Step 2: Check output fields
Output hasfullNamewith "Alice" andageInMonthswith 300. Nonameoragefields remain.Final Answer:
[{ "fullName": "Alice", "ageInMonths": 300 }] -> Option DQuick Check:
Rename + multiply age = output [OK]
- Expecting original fields to remain without including them
- Confusing field names after renaming
- Forgetting to exclude _id if not wanted
$project stage:{ $project: { fullName: "$name", ageInMonths: { $multiply: ["age", 12] }, _id: 0 } }Solution
Step 1: Check field references in expressions
In MongoDB aggregation, to reference a field inside expressions, prefix with$. Here, "age" is missing$.Step 2: Validate other parts
$multiplyis valid in$project. Excluding_idis allowed. Renaming fields is allowed.Final Answer:
Field name "age" should be prefixed with $ to reference the field. -> Option CQuick Check:
Field references need $ prefix [OK]
- Omitting $ before field names in expressions
- Thinking $multiply is invalid in $project
- Believing _id cannot be excluded
firstName, lastName, and birthYear. Write a $project stage that outputs fullName as concatenation of first and last names separated by a space, and age calculated as 2024 minus birthYear. Which is the correct stage?Solution
Step 1: Build fullName using $concat with spaces
Use$concatwith"$firstName", a space string, and"$lastName"to join names with a space.Step 2: Calculate age using $subtract
SubtractbirthYearfield from 2024 using$subtract. Field references need$.Step 3: Check each option
{ $project: { fullName: { $concat: ["$firstName", " ", "$lastName"] }, age: { $subtract: [2024, "$birthYear"] }, _id: 0 } } correctly uses$concatwith space and$subtractwith field references. { $project: { fullName: "$firstName $lastName", age: 2024 - "$birthYear", _id: 0 } } uses invalid string concatenation and arithmetic. { $project: { fullName: { $concat: ["firstName", " ", "lastName"] }, age: { $subtract: [2024, "birthYear"] }, _id: 0 } } misses$on fields. { $project: { fullName: { $concat: ["$firstName", "$lastName"] }, age: { $subtract: ["birthYear", 2024] }, _id: 0 } } misses space and reverses subtraction.Final Answer:
{ $project: { fullName: { $concat: ["$firstName", " ", "$lastName"] }, age: { $subtract: [2024, "$birthYear"] }, _id: 0 } } -> Option AQuick Check:
Use $concat with space and $subtract with $field [OK]
- Forgetting $ before field names
- Concatenating fields without spaces
- Subtracting in wrong order
- Using string expressions instead of operators
Ready to prove it?
Pass the test and this pattern moves unknown
