Bird
Raised Fist0
MongoDBquery~30 mins

$facet for multiple pipelines in MongoDB - Mini Project: Build & Apply

Choose your learning style10 modes available
Using $facet for Multiple Pipelines in MongoDB Aggregation
📖 Scenario: You work at a bookstore that keeps its sales data in a MongoDB collection called sales. Each document records a book sale with fields like title, genre, price, and copies_sold.The manager wants to see two things at once: the total revenue per genre and the top 3 best-selling books overall.
🎯 Goal: Build a MongoDB aggregation query using $facet to run two pipelines simultaneously:One pipeline calculates total revenue per genre.The other pipeline finds the top 3 best-selling books overall.
📋 What You'll Learn
Create a sales collection with exact documents provided.
Add a variable minCopies set to 5 to filter popular books.
Write an aggregation query using $facet with two pipelines: revenueByGenre and topBooks.
In revenueByGenre, group by genre and sum total revenue (price * copies_sold).
In topBooks, filter books with copies_sold >= minCopies, sort by copies_sold descending, and limit to 3.
Complete the aggregation query with the db.sales.aggregate() call.
💡 Why This Matters
🌍 Real World
Bookstores and retail businesses often need to analyze sales data in multiple ways simultaneously, such as revenue by category and best sellers.
💼 Career
Understanding $facet helps database developers and analysts write efficient queries that return multiple summaries in one request, saving time and resources.
Progress0 / 4 steps
1
Create the sales collection with sample data
Create a variable called sales and assign it an array of these exact documents: {"title": "Book A", "genre": "Fiction", "price": 10, "copies_sold": 4}, {"title": "Book B", "genre": "Fiction", "price": 15, "copies_sold": 7}, {"title": "Book C", "genre": "Non-Fiction", "price": 20, "copies_sold": 5}, {"title": "Book D", "genre": "Non-Fiction", "price": 25, "copies_sold": 3}, {"title": "Book E", "genre": "Fiction", "price": 8, "copies_sold": 10}
MongoDB
Hint
Create a list named sales with the exact book documents as shown.
2
Add a variable minCopies to filter popular books
Create a variable called minCopies and set it to 5.
MongoDB
Hint
Just create a variable named minCopies and assign 5 to it.
3
Write the aggregation query using $facet with two pipelines
Create a variable called aggregationQuery and assign it the MongoDB aggregation pipeline array that uses $facet with two pipelines: revenueByGenre and topBooks. In revenueByGenre, group by genre and sum total revenue as totalRevenue (calculate price * copies_sold). In topBooks, filter documents where copies_sold is greater than or equal to minCopies, sort by copies_sold descending, and limit to 3.
MongoDB
Hint
Use $facet with two pipelines named revenueByGenre and topBooks as described.
4
Complete the aggregation call with db.sales.aggregate()
Write a line of code that assigns to a variable called result the call to db.sales.aggregate() passing the aggregationQuery variable.
MongoDB
Hint
Call db.sales.aggregate() with aggregationQuery and assign to result.

Practice

(1/5)
1. What does the $facet stage do in a MongoDB aggregation pipeline?
easy
A. Sorts documents in ascending or descending order.
B. Filters documents based on a condition.
C. Joins two collections together.
D. Runs multiple pipelines on the same input data and returns results in one document.

Solution

  1. Step 1: Understand the purpose of $facet

    $facet allows running multiple aggregation pipelines on the same input data simultaneously.
  2. Step 2: Identify the output structure

    The output is a single document containing separate arrays for each pipeline's results.
  3. Final Answer:

    Runs multiple pipelines on the same input data and returns results in one document. -> Option D
  4. Quick Check:

    $facet = multiple pipelines, one output document [OK]
Hint: Remember: $facet runs many pipelines at once [OK]
Common Mistakes:
  • Thinking $facet filters or sorts data
  • Confusing $facet with $lookup
  • Assuming it returns multiple documents instead of one
2. Which of the following is the correct syntax to use $facet in a MongoDB aggregation pipeline?
easy
A. { $facet: { pipeline1: [ { $match: {} } ], pipeline2: [ { $group: {} } ] } }
B. { $facet: [ { $match: {} }, { $group: {} } ] }
C. { $facet: { $match: {}, $group: {} } }
D. { $facet: { pipeline1: { $match: {} }, pipeline2: { $group: {} } } }

Solution

  1. Step 1: Recall $facet syntax

    $facet expects an object where each key is a pipeline name and the value is an array of pipeline stages.
  2. Step 2: Check each option

    { $facet: { pipeline1: [ { $match: {} } ], pipeline2: [ { $group: {} } ] } } correctly uses an object with arrays of stages. Options A, C, and D misuse arrays or objects for stages.
  3. Final Answer:

    { $facet: { pipeline1: [ { $match: {} } ], pipeline2: [ { $group: {} } ] } } -> Option A
  4. Quick Check:

    $facet needs named pipelines with arrays of stages [OK]
Hint: Use named keys with arrays of stages inside $facet [OK]
Common Mistakes:
  • Using arrays directly instead of named pipelines
  • Putting stages as objects instead of arrays
  • Missing pipeline names inside $facet
3. Given the collection sales with documents like { item: 'apple', price: 10, quantity: 2 }, what will be the output of this aggregation?
{ $facet: { totalSales: [ { $group: { _id: null, total: { $sum: { $multiply: ["$price", "$quantity"] } } } } ], items: [ { $group: { _id: "$item", count: { $sum: "$quantity" } } } ] } }
medium
A. [{ totalSales: [{ _id: null, total: 20 }], items: [{ _id: 'apple', count: 2 }] }]
B. [{ totalSales: 20, items: [{ _id: 'apple', count: 2 }] }]
C. [{ totalSales: [{ total: 20 }], items: [{ _id: 'apple', count: 2 }] }]
D. [{ totalSales: [{ _id: null, total: 12 }], items: [{ _id: 'apple', count: 2 }] }]

Solution

  1. Step 1: Calculate totalSales pipeline

    Multiply price (10) by quantity (2) = 20, sum is 20, grouped with _id null.
  2. Step 2: Calculate items pipeline

    Group by item 'apple', sum quantity 2, so count is 2.
  3. Final Answer:

    [{ totalSales: [{ _id: null, total: 20 }], items: [{ _id: 'apple', count: 2 }] }] -> Option A
  4. Quick Check:

    Each pipeline returns array with grouped results [OK]
Hint: Remember $facet outputs arrays for each pipeline [OK]
Common Mistakes:
  • Expecting direct values instead of arrays
  • Mixing up _id values in group results
  • Forgetting $multiply inside $sum
4. You wrote this aggregation but get an error:
{ $facet: { sales: { $group: { _id: "$item", total: { $sum: "$quantity" } } } } }
What is the mistake?
medium
A. The $facet stage must be the last stage in the pipeline.
B. You cannot use $group inside $facet.
C. Pipeline stages inside $facet must be arrays, not objects.
D. The field names inside $group are incorrect.

Solution

  1. Step 1: Check $facet syntax requirements

    Each pipeline inside $facet must be an array of stages, not a single object.
  2. Step 2: Identify the error in the given code

    The pipeline 'sales' is given as an object with $group, missing array brackets.
  3. Final Answer:

    Pipeline stages inside $facet must be arrays, not objects. -> Option C
  4. Quick Check:

    $facet pipelines = arrays of stages [OK]
Hint: Always wrap pipeline stages in arrays inside $facet [OK]
Common Mistakes:
  • Using object instead of array for pipeline stages
  • Assuming $group is disallowed inside $facet
  • Thinking $facet must be last stage
5. You want to get both the average price and a list of unique items from a products collection in one query. Which $facet pipeline correctly achieves this?
hard
A. { $facet: [ { $group: { _id: null, avg: { $avg: "$price" } } }, { $group: { _id: "$item" } } ] }
B. { $facet: { avgPrice: [ { $group: { _id: null, avg: { $avg: "$price" } } } ], uniqueItems: [ { $group: { _id: "$item" } } ] } }
C. { $facet: { avgPrice: { $avg: "$price" }, uniqueItems: { $addToSet: "$item" } } }
D. { $facet: { avgPrice: [ { $avg: "$price" } ], uniqueItems: [ { $addToSet: "$item" } ] } }

Solution

  1. Step 1: Understand $facet structure

    Each facet must be a named pipeline with an array of stages.
  2. Step 2: Check each option

    { $facet: { avgPrice: [ { $group: { _id: null, avg: { $avg: "$price" } } } ], uniqueItems: [ { $group: { _id: "$item" } } ] } } correctly uses two pipelines: one groups to get average price, the other groups by item to get unique items. Options B, C, and D misuse arrays or operators incorrectly.
  3. Final Answer:

    { $facet: { avgPrice: [ { $group: { _id: null, avg: { $avg: "$price" } } } ], uniqueItems: [ { $group: { _id: "$item" } } ] } } -> Option B
  4. Quick Check:

    Named pipelines with arrays of stages = correct $facet usage [OK]
Hint: Use separate pipelines with arrays for each facet [OK]
Common Mistakes:
  • Using $facet with arrays instead of named pipelines
  • Trying to use aggregation operators directly inside $facet
  • Not grouping properly to get unique items
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard