📖 Scenario: You work for an online store that wants to create a simple sales report dashboard. The dashboard will show total sales and the number of orders per product category.
🎯 Goal: Build a MongoDB aggregation pipeline step-by-step to calculate total sales and order counts grouped by product category.
📋 What You'll Learn
Create a sales collection with sample sales documents
Add a filter stage to select sales from the last month
Group sales by category to calculate total sales amount and order count
Sort the results by total sales in descending order
💡 Why This Matters
🌍 Real World
Aggregation pipelines are used in real dashboards to summarize and analyze sales data quickly.
💼 Career
Understanding aggregation is essential for data analysts and backend developers working with MongoDB to build reports.
Progress0 / 4 steps
1
DATA SETUP: Create the sales collection with sample documents
Create a variable called sales that contains an array of 5 sales documents. Each document must have these exact fields and values: { product: 'Laptop', category: 'Electronics', amount: 1200, date: new Date('2024-05-10') }, { product: 'Headphones', category: 'Electronics', amount: 150, date: new Date('2024-05-15') }, { product: 'Coffee Maker', category: 'Home Appliances', amount: 80, date: new Date('2024-05-20') }, { product: 'Blender', category: 'Home Appliances', amount: 60, date: new Date('2024-04-25') }, { product: 'Notebook', category: 'Stationery', amount: 5, date: new Date('2024-05-18') }.
MongoDB
Hint
Use const sales = [ ... ] and include the exact documents with the given fields and values.
2
CONFIGURATION: Define the date filter for last month sales
Create a variable called lastMonth and set it to a JavaScript Date object representing May 1, 2024.
MongoDB
Hint
Use const lastMonth = new Date('2024-05-01') to set the date filter.
3
CORE LOGIC: Build the aggregation pipeline to filter and group sales
Create a variable called pipeline that is an array with these stages: 1) a $match stage to filter sales with date greater than or equal to lastMonth, 2) a $group stage that groups by category and calculates totalSales as the sum of amount and orderCount as the count of documents.
MongoDB
Hint
Use { $match: { date: { $gte: lastMonth } } } and { $group: { _id: "$category", totalSales: { $sum: "$amount" }, orderCount: { $sum: 1 } } } in the pipeline array.
4
COMPLETION: Add a $sort stage to order results by total sales
Add a $sort stage to the pipeline array that sorts documents by totalSales in descending order.
MongoDB
Hint
Add { $sort: { totalSales: -1 } } as the last stage in the pipeline array.
Practice
(1/5)
1. What is the main purpose of using the $group stage in a MongoDB aggregation pipeline for reporting dashboards?
easy
A. To add new fields to documents without changing existing ones
B. To combine documents and calculate summary values like totals or averages
C. To sort documents in ascending or descending order
D. To filter documents based on specific conditions
Solution
Step 1: Understand the role of $group
The $group stage collects documents into groups and calculates summary statistics like sums or averages.
Step 2: Compare with other stages
$match filters, $sort orders, and $addFields adds fields, but only $group aggregates data.
Final Answer:
To combine documents and calculate summary values like totals or averages -> Option B
Quick Check:
$group = summary aggregation [OK]
Hint: Remember $group is for summarizing data by categories [OK]
Common Mistakes:
Confusing $group with $match filtering
Thinking $group sorts data
Assuming $group adds fields without aggregation
2. Which of the following is the correct syntax to start an aggregation pipeline in MongoDB?
easy
A. db.collection.aggregate([{ $match: { status: 'active' } }])
B. db.collection.find({ $match: { status: 'active' } })
C. db.collection.group({ status: 'active' })
D. db.collection.aggregateMatch({ status: 'active' })
Solution
Step 1: Identify the aggregation method
The correct method to start aggregation is aggregate() with an array of stages.
Step 2: Check syntax correctness
db.collection.aggregate([{ $match: { status: 'active' } }]) is valid; others use wrong methods or syntax.
Final Answer:
db.collection.aggregate([{ $match: { status: 'active' } }]) -> Option A
Quick Check:
aggregate() starts pipeline [OK]
Hint: Use aggregate() with an array of stages to start [OK]
Common Mistakes:
Using find() instead of aggregate() for pipelines
Trying to use group() as a method
Incorrect method names like aggregateMatch()
3. Given the collection sales with documents like { product: 'A', quantity: 5 } and { product: 'B', quantity: 3 }, what will this aggregation return?
D. The $project stage uses a field not present in the grouped output
Solution
Step 1: Check fields after $group
After grouping by _id: '$customerId', the output fields are _id and total. The original customerId field is renamed to _id.
Step 2: Analyze $project stage
The $project tries to include customerId, which does not exist; it should use _id instead.
Final Answer:
The $project stage uses a field not present in the grouped output -> Option D
Quick Check:
Use _id after $group, not original field [OK]
Hint: After $group, use _id field names in $project [OK]
Common Mistakes:
Assuming original fields remain after $group
Placing $sort before $group incorrectly
Misusing $sum outside $group
5. You want to create a dashboard showing the average order amount per customer, but only for customers with more than 3 orders. Which aggregation pipeline correctly achieves this?