MongoDB aggregation Pipelines simplified
MongoDB Aggregation Pipeline stages
MongoDB’s aggregation pipeline is a powerful framework for transforming, filtering, and analyzing data in collections similar to SQL’s GROUP BY, JOIN, WHERE, etc.
🧱 Basic Structure
An aggregation pipeline is an array of stages, each stage transforms the documents and passes them to the next stage.
db.collection.aggregate([
{ <stage1> },
{ <stage2> },
...
])
1️⃣ $match – Filtering Documents
Works like the find() query. Filters documents based on conditions.
Example:
db.orders.aggregate([
{ $match: { status: "delivered" } }
])
✅ Returns only documents where status = "delivered".
2️⃣ $project – Select or Reshape Fields
Used to include/exclude fields or create computed fields.
Example:
db.orders.aggregate([
{
$project: {
_id: 0,
item: 1,
total: { $multiply: ["$price", "$quantity"] }
}
}
])
✅ Outputs only item and a computed field total.
3️⃣ $group – Group Documents & Aggregate Data
Groups documents by a key and applies aggregation operators (like $sum, $avg, etc.).
Example:
db.orders.aggregate([
{
$group: {
_id: "$customerId",
totalSpent: { $sum: { $multiply: ["$price", "$quantity"] } },
numOrders: { $sum: 1 }
}
}
])
✅ Groups by customer and calculates:
- Total spent
- Number of orders
4️⃣ $sort – Sort Results
Sorts documents by one or more fields.
Example:
db.orders.aggregate([
{ $sort: { total: -1 } } // descending
])
✅ Sorts by total in descending order.
5️⃣ $limit and $skip – Pagination
-
$limit: Restricts the number of documents. -
$skip: Skips a number of documents.
Example:
db.orders.aggregate([
{ $sort: { date: -1 } },
{ $skip: 10 },
{ $limit: 5 }
])
✅ Skips first 10, returns next 5 (useful for pagination).
6️⃣ $unwind – Deconstruct Arrays
Splits array fields into multiple documents (one per element).
Example:
db.orders.aggregate([
{ $unwind: "$items" }
])
✅ If a document has an array items: [a, b, c], it becomes 3 documents – one for each item.
7️⃣ $lookup – Join with Another Collection
Performs a left outer join between two collections.
Example:
db.orders.aggregate([
{
$lookup: {
from: "customers",
localField: "customerId",
foreignField: "_id",
as: "customer"
}
}
])
✅ Adds matching customer info to each order under the field customer.
8️⃣ $addFields – Add or Modify Fields
Adds new fields or modifies existing ones.
Example:
db.orders.aggregate([
{
$addFields: {
total: { $multiply: ["$price", "$quantity"] },
statusUpper: { $toUpper: "$status" }
}
}
])
✅ Adds computed total and uppercase status.
9️⃣ $count – Count Documents
Counts the number of documents in the pipeline.
Example:
db.orders.aggregate([
{ $match: { status: "pending" } },
{ $count: "pendingOrders" }
])
✅ Returns { pendingOrders: 12 }.
🔟 $facet – Multiple Pipelines in One
Allows parallel aggregations on the same dataset.
Example:
db.orders.aggregate([
{
$facet: {
totalByCustomer: [
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } }
],
avgOrderValue: [
{ $group: { _id: null, avg: { $avg: "$amount" } } }
]
}
}
])
✅ Runs two aggregations in one pipeline.
1️⃣1️⃣ $bucket – Categorize Into Ranges
Groups values into defined ranges (buckets).
Example:
db.sales.aggregate([
{
$bucket: {
groupBy: "$amount",
boundaries: [0, 100, 500, 1000],
default: "Other",
output: { count: { $sum: 1 } }
}
}
])
✅ Categorizes sales by amount ranges.
1️⃣2️⃣ $out – Write Results to a Collection
Saves aggregation results into a new collection.
Example:
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $out: "completedOrders" }
])
✅ Writes output into a new collection completedOrders.
1️⃣3️⃣ $merge – Merge Results into an Existing Collection
Similar to $out, but can update or insert documents.
Example:
db.orders.aggregate([
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } },
{ $merge: { into: "customerTotals", whenMatched: "merge", whenNotMatched: "insert" } }
])
✅ Updates or inserts aggregated data into customerTotals.
Let me know if this helped you in some way.