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.

Similar Posts