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.
 

 
    
Top comments (0)