Paramclasses Academy - Blog

Tutorials Details

←
Post 21 of 35
→

MongoDB Aggregation Pipeline Stages: $match, $group, $sort and $project

MongoDB Aggregation Pipeline Stages: $match, $group, $sort and $project

November 5, 2026

MongoDB Aggregation Pipeline Stages: $match, $group, $sort and $project

Introduction

MongoDB Aggregation Pipeline is a powerful feature used to process, analyze, and transform documents stored in a collection.

An aggregation pipeline consists of multiple stages. Each stage performs a particular operation and passes its output to the next stage.

Among the most commonly used stages are:

  • $match – Filters documents based on conditions.

  • $group – Groups documents and performs calculations.

  • $sort – Arranges documents in ascending or descending order.

  • $project – Selects, excludes, or transforms fields in the output.

In this tutorial, you will learn how these four important aggregation stages work individually and how to combine them in a practical MongoDB project using MongoDB Shell (mongosh).

1. What Is an Aggregation Pipeline Stage?

An aggregation pipeline stage is an individual processing step inside a MongoDB aggregation pipeline.

Each stage receives documents, performs an operation, and passes the resulting documents to the next stage.

Basic Syntax:

db.collection.aggregate([
  { $stage1: { /* operation */ } },
  { $stage2: { /* operation */ } },
  { $stage3: { /* operation */ } }
])

For example:

db.orders.aggregate([
  { $match: { status: "Completed" } },
  { $group: { _id: "$city", totalOrders: { $sum: 1 } } },
  { $sort: { totalOrders: -1 } },
  { $project: { _id: 0, city: "$_id", totalOrders: 1 } }
])

This pipeline filters completed orders, groups them by city, sorts the results, and selects the required output fields.

2. Create a Database and Collection

Before learning the stages, let's create a sample database and collection.

Open MongoDB Shell (mongosh).

Create or switch to a database:

use salesDB

Create an orders collection:

db.createCollection("orders")

Insert sample documents:

db.orders.insertMany([
  {
    customer: "Rahul",
    city: "Raipur",
    product: "Laptop",
    amount: 55000,
    status: "Completed"
  },
  {
    customer: "Priya",
    city: "Delhi",
    product: "Mobile",
    amount: 25000,
    status: "Completed"
  },
  {
    customer: "Amit",
    city: "Raipur",
    product: "Keyboard",
    amount: 2000,
    status: "Pending"
  },
  {
    customer: "Neha",
    city: "Mumbai",
    product: "Laptop",
    amount: 60000,
    status: "Completed"
  },
  {
    customer: "Karan",
    city: "Delhi",
    product: "Mouse",
    amount: 1000,
    status: "Completed"
  },
  {
    customer: "Anjali",
    city: "Mumbai",
    product: "Mobile",
    amount: 30000,
    status: "Pending"
  }
])

Verify the records:

db.orders.find()

Now we can practice the four important aggregation stages.

3. MongoDB $match Stage

The $match stage filters documents based on specified conditions.

It works similarly to the filtering conditions used in MongoDB's find() method.

Syntax:

{
  $match: {
    field: value
  }
}

Example 1: Find Completed Orders

db.orders.aggregate([
  {
    $match: {
      status: "Completed"
    }
  }
])

Explanation:

  • $match filters the documents.

  • status is the field being checked.

  • "Completed" is the required value.

Only orders with Completed status are returned.

Example 2: Find Orders Above 20000

db.orders.aggregate([
  {
    $match: {
      amount: { $gt: 20000 }
    }
  }
])

Here, $gt means greater than.

Example 3: Filter by Multiple Conditions

db.orders.aggregate([
  {
    $match: {
      status: "Completed",
      city: "Raipur"
    }
  }
])

This query returns completed orders from Raipur.

You can use comparison and logical operators inside $match to create more advanced filtering conditions.

4. MongoDB $group Stage

The $group stage groups documents based on a specified expression.

It is commonly used for calculating totals, counts, averages, minimum values, and maximum values.

Syntax:

{
  $group: {
    _id: "$field",
    result: { $sum: "$amount" }
  }
}

The _id field specifies the grouping expression.

Example 1: Group Orders by City

db.orders.aggregate([
  {
    $group: {
      _id: "$city",
      totalOrders: { $sum: 1 }
    }
  }
])

Explanation:

  • _id: "$city" groups orders by city.

  • $sum: 1 counts each document in its group.

  • totalOrders stores the total number of orders.

Example 2: Calculate Total Sales by City

db.orders.aggregate([
  {
    $group: {
      _id: "$city",
      totalSales: { $sum: "$amount" }
    }
  }
])

This calculates the total sales amount for each city.

Example 3: Calculate Average Order Amount

db.orders.aggregate([
  {
    $group: {
      _id: "$city",
      averageAmount: { $avg: "$amount" }
    }
  }
])

This calculates the average order amount for every city.

Common Accumulator Operators

Operator Purpose
$sum Calculates the total
$avg Calculates the average
$min Finds the minimum value
$max Finds the maximum value
$first Returns the first value in the group input
$last Returns the last value in the group input

Remember that $first and $last depend on the order of documents entering the $group stage. Use $sort before $group when a particular order is required.

5. MongoDB $sort Stage

The $sort stage arranges documents according to one or more fields.

Syntax:

{
  $sort: {
    field: 1
  }
}

MongoDB supports two sorting directions:

  • 1 – Ascending order.

  • -1 – Descending order.

Example 1: Sort Orders by Amount in Ascending Order

db.orders.aggregate([
  {
    $sort: {
      amount: 1
    }
  }
])

This displays orders from the lowest amount to the highest amount.

Example 2: Sort Orders by Amount in Descending Order

db.orders.aggregate([
  {
    $sort: {
      amount: -1
    }
  }
])

This displays orders from the highest amount to the lowest amount.

Example 3: Sort by Multiple Fields

db.orders.aggregate([
  {
    $sort: {
      city: 1,
      amount: -1
    }
  }
])

This sorts documents by city in ascending order and then by amount in descending order within each city.

6. MongoDB $project Stage

The $project stage controls which fields appear in the aggregation output.

It can include fields, exclude fields, rename fields, and create calculated fields.

Syntax:

{
  $project: {
    field1: 1,
    field2: 1,
    field3: 0
  }
}

Example 1: Display Selected Fields

db.orders.aggregate([
  {
    $project: {
      customer: 1,
      product: 1,
      amount: 1
    }
  }
])

This displays the selected fields. The _id field is included by default unless explicitly excluded.

Example 2: Hide the _id Field

db.orders.aggregate([
  {
    $project: {
      _id: 0,
      customer: 1,
      amount: 1
    }
  }
])

Here, _id: 0 excludes the _id field from the output.

Example 3: Rename a Field in the Output

db.orders.aggregate([
  {
    $project: {
      _id: 0,
      customerName: "$customer",
      orderAmount: "$amount"
    }
  }
])

This creates output fields named customerName and orderAmount using the original document fields.

Example 4: Create a Calculated Field

db.orders.aggregate([
  {
    $project: {
      customer: 1,
      amount: 1,
      tax: {
        $multiply: ["$amount", 0.10]
      }
    }
  }
])

This calculates a tax value equal to 10% of the order amount and includes it in the output.

7. Combine $match, $group, $sort and $project

Now let's combine all four stages in one practical aggregation pipeline.

Requirement:

Find completed orders, group them by city, calculate total sales and order count, sort cities by total sales, and display a clean result.

MongoDB Query:

db.orders.aggregate([
  {
    $match: {
      status: "Completed"
    }
  },
  {
    $group: {
      _id: "$city",
      totalSales: { $sum: "$amount" },
      totalOrders: { $sum: 1 }
    }
  },
  {
    $sort: {
      totalSales: -1
    }
  },
  {
    $project: {
      _id: 0,
      city: "$_id",
      totalSales: 1,
      totalOrders: 1
    }
  }
])

Step-by-Step Explanation

Step 1: $match

{
  $match: {
    status: "Completed"
  }
}

Filters the collection and selects only completed orders.

Step 2: $group

{
  $group: {
    _id: "$city",
    totalSales: { $sum: "$amount" },
    totalOrders: { $sum: 1 }
  }
}

Groups the selected orders by city and calculates total sales and order count.

Step 3: $sort

{
  $sort: {
    totalSales: -1
  }
}

Sorts cities by total sales in descending order.

Step 4: $project

{
  $project: {
    _id: 0,
    city: "$_id",
    totalSales: 1,
    totalOrders: 1
  }
}

Displays the required fields and renames _id to city.

Expected Result

The result will be similar to:

[
  {
    city: "Mumbai",
    totalSales: 60000,
    totalOrders: 1
  },
  {
    city: "Raipur",
    totalSales: 55000,
    totalOrders: 1
  },
  {
    city: "Delhi",
    totalSales: 26000,
    totalOrders: 2
  }
]

The exact output depends on the documents in your collection.

8. Important Differences Between the Four Stages

Stage Main Purpose Example
$match Filters documents Select completed orders
$group Groups and calculates Total sales by city
$sort Arranges results Highest sales first
$project Selects and transforms fields Display city and total sales

These stages perform different tasks, but they become especially useful when combined in a pipeline.

9. Best Practices for Aggregation Pipeline Stages

Follow these practices when building MongoDB aggregation pipelines:

  1. Use $match early when it can reduce the number of documents processed by later stages.

  2. Use suitable indexes to support filtering and sorting operations.

  3. Group documents only when the required analysis needs grouping.

  4. Use $sort carefully when processing large datasets.

  5. Use $project to shape the output fields you actually need.

  6. Keep pipeline stages readable and organized.

  7. Test your pipeline with realistic sample data.

  8. Use explain() to inspect query execution and identify performance issues.

10. Practical Exercise

Create a database named companyDB and a collection named employees.

Insert at least six employee documents containing:

  • employeeName

  • department

  • city

  • salary

  • status

Now complete these tasks:

Task 1: Display employees using the aggregation method.

Task 2: Use $match to find employees from the IT department.

Task 3: Use $match to find employees whose salary is greater than 30000.

Task 4: Use $group to group employees by department.

Task 5: Calculate average salary using $avg.

Task 6: Calculate total salary by department using $sum.

Task 7: Use $sort to arrange employees by salary in descending order.

Task 8: Use $project to display only employeeName, department, and salary.

Task 9: Create a pipeline combining $match and $sort.

Task 10: Create a pipeline combining all four stages: $match, $group, $sort, and $project.

11. Frequently Asked Questions (FAQs)

Q1. What is the $match stage in MongoDB?

$match filters documents according to specified conditions in an aggregation pipeline.

Q2. What is the $group stage used for?

$group groups documents using a specified expression and performs calculations using accumulator operators such as $sum, $avg, $min, and $max.

Q3. What is the use of $sort in MongoDB aggregation?

$sort arranges documents in ascending or descending order based on one or more fields.

Q4. What does $project do in MongoDB?

$project selects, excludes, renames, or calculates fields in the output documents.

Q5. Can we use $match and $group together?

Yes. You can use $match before $group to filter documents before performing grouping and calculations.

Q6. Is the order of aggregation stages important?

Yes. Each stage receives the output of the previous stage, so changing the order can change the result and performance.

Q7. Can we use multiple $sort fields?

Yes. MongoDB allows sorting by multiple fields in one $sort stage.

Conclusion

MongoDB Aggregation Pipeline stages are essential for filtering, grouping, sorting, and transforming database documents.

In this tutorial, we learned four important stages: $match, $group, $sort, and $project.

We also combined all four stages to analyze completed orders, calculate total sales, group records by city, and display organized results.

Understanding these stages will help you build more powerful MongoDB queries and develop efficient data-driven applications.

Practice the examples in mongosh to strengthen your MongoDB aggregation skills.

←
Post 21 of 35
→