Lesson 24 of 50 – Introduction to Aggregation in MongoDB
48%

Introduction to Aggregation in MongoDB

Aggregation in MongoDB is used to process documents and calculate useful results. It can filter records, group documents, calculate totals, sort results, and generate reports.

For example, a coaching institute can use aggregation to calculate total student fees, count students in each course, and find the average marks of students.

1. What Is Aggregation?

Aggregation processes a collection of documents and produces results based on the operations we specify.

Consider these student documents:

{
    name: "Rahul",
    course: "Java",
    fee: 5000
}
{
    name: "Priya",
    course: "Python",
    fee: 6000
}
{
    name: "Aman",
    course: "Java",
    fee: 4500
}

Using aggregation, we can calculate:

  • Total number of students.
  • Total fees collected in the records.
  • Average student fee.
  • Number of students in each course.
  • Total fees collected for each course.

2. The aggregate() Method

MongoDB provides the aggregate() method to run an aggregation pipeline.

Syntax
db.collection.aggregate([
    { stage1 },
    { stage2 },
    { stage3 }
])

The pipeline contains stages. Each stage performs an operation on the documents and passes its results to the next stage.

Simple Example
db.students.aggregate([
    {
        $match: {
            course: "Java"
        }
    }
])

The $match stage returns documents whose course is Java.

3. What Is an Aggregation Pipeline?

An aggregation pipeline is a sequence of stages. The output of one stage becomes the input of the next stage.

Example Pipeline
db.students.aggregate([
    {
        $match: {
            course: "Java"
        }
    },
    {
        $sort: {
            fee: -1
        }
    },
    {
        $limit: 5
    }
])

This pipeline performs three operations:

  1. $match selects Java students.
  2. $sort sorts them by fee from highest to lowest.
  3. $limit returns up to five matching documents.

4. The $match Stage

The $match stage filters documents according to a specified condition.

Example: Find Java Students
db.students.aggregate([
    {
        $match: {
            course: "Java"
        }
    }
])
Example: Find Students with Fees Above 5000
db.students.aggregate([
    {
        $match: {
            fee: { $gt: 5000 }
        }
    }
])

The second pipeline returns only documents where the fee is greater than 5000.

5. The $group Stage

The $group stage groups documents using a specified key. It can also calculate totals, counts, averages, minimums, and maximums.

Example: Count Students in Each Course
db.students.aggregate([
    {
        $group: {
            _id: "$course",
            totalStudents: {
                $sum: 1
            }
        }
    }
])

Here, _id: "$course" groups documents by course. The expression $sum: 1 counts each document in its group.

Example output:

{
    _id: "Java",
    totalStudents: 2
}
{
    _id: "Python",
    totalStudents: 1
}

The exact order of the returned groups is not guaranteed unless you add a sorting stage.

6. Calculate the Total Using $sum

The $sum accumulator calculates a sum inside a group.

Example: Calculate Total Fees
db.students.aggregate([
    {
        $group: {
            _id: null,
            totalFees: {
                $sum: "$fee"
            }
        }
    }
])

The expression _id: null places all input documents into one group. The sum of their fee values is returned as totalFees.

For the sample documents, the total is 15500.

Example: Count All Students
db.students.aggregate([
    {
        $group: {
            _id: null,
            totalStudents: {
                $sum: 1
            }
        }
    }
])

This returns the number of documents in the input collection that reach the group stage.

7. Calculate the Average Using $avg

The $avg accumulator calculates the average of numeric values.

Example: Average Student Fee
db.students.aggregate([
    {
        $group: {
            _id: null,
            averageFee: {
                $avg: "$fee"
            }
        }
    }
])

For the sample fees of 5000, 6000, and 4500, the average is approximately 5166.67.

Average Fee by Course
db.students.aggregate([
    {
        $group: {
            _id: "$course",
            averageFee: {
                $avg: "$fee"
            }
        }
    }
])

This calculates a separate average fee for each course.

8. The $sort Stage

The $sort stage arranges documents in ascending or descending order.

Ascending Order
db.students.aggregate([
    {
        $sort: {
            fee: 1
        }
    }
])
Descending Order
db.students.aggregate([
    {
        $sort: {
            fee: -1
        }
    }
])

Use 1 for ascending order and -1 for descending order.

9. The $project Stage

The $project stage selects fields, excludes fields, or creates calculated fields in the pipeline output.

Example: Display Name and Course
db.students.aggregate([
    {
        $project: {
            _id: 0,
            name: 1,
            course: 1
        }
    }
])

This output contains only the name and course fields.

Example: Create a Fee Category
db.students.aggregate([
    {
        $project: {
            _id: 0,
            name: 1,
            fee: 1,
            feeCategory: {
                $cond: [
                    { $gte: ["$fee", 5000] },
                    "High",
                    "Standard"
                ]
            }
        }
    }
])

The $cond expression creates a calculated field named feeCategory. Fees of 5000 or more are categorized as High; other fees are categorized as Standard.

10. The $limit and $skip Stages

Aggregation pipelines provide $limit and $skip stages for controlling the number of documents returned.

Example: Return Three Documents
db.students.aggregate([
    {
        $limit: 3
    }
])
Example: Skip Two Documents
db.students.aggregate([
    {
        $skip: 2
    }
])
Example: Sort and Return Two Highest Fees
db.students.aggregate([
    {
        $sort: {
            fee: -1
        }
    },
    {
        $limit: 2
    }
])

Sorting before limiting makes the result useful when selecting the highest or lowest values.

11. Complete Aggregation Example

The following pipeline finds Java students, groups them by course, counts students, and calculates their total fees.

db.students.aggregate([
    {
        $match: {
            course: "Java"
        }
    },
    {
        $group: {
            _id: "$course",
            totalStudents: {
                $sum: 1
            },
            totalFees: {
                $sum: "$fee"
            },
            averageFee: {
                $avg: "$fee"
            }
        }
    },
    {
        $project: {
            _id: 0,
            course: "$_id",
            totalStudents: 1,
            totalFees: 1,
            averageFee: 1
        }
    }
])

This pipeline performs four tasks:

  1. Filters Java students with $match.
  2. Groups the matching students with $group.
  3. Calculates the student count, total fees, and average fee.
  4. Formats the output fields with $project.

12. Important Points to Remember

  • aggregate() runs an aggregation pipeline.
  • $match filters documents.
  • $group groups documents and calculates results.
  • $sum calculates totals or counts when used with 1.
  • $avg calculates the average of numeric values.
  • $sort sorts pipeline results.
  • $project selects or calculates output fields.
  • $limit limits the number of documents.
  • $skip skips a specified number of documents.
  • Stage order matters because each stage processes the previous stage's output.

13. Practical Assignment

Create a collection named practice_aggregation and insert these documents:

db.practice_aggregation.insertMany([
    {
        _id: 1,
        name: "Rahul",
        course: "Java",
        fee: 5000,
        marks: 80
    },
    {
        _id: 2,
        name: "Priya",
        course: "Python",
        fee: 6000,
        marks: 90
    },
    {
        _id: 3,
        name: "Aman",
        course: "Java",
        fee: 4500,
        marks: 75
    },
    {
        _id: 4,
        name: "Neha",
        course: "Python",
        fee: 7000,
        marks: 95
    },
    {
        _id: 5,
        name: "Karan",
        course: "Java",
        fee: 5500,
        marks: 85
    }
])
Complete these tasks:
  1. Display all Java students using $match.
  2. Count students in each course using $group.
  3. Calculate the total fees of all students.
  4. Calculate the average marks of all students.
  5. Calculate the total fees for each course.
  6. Sort students by marks from highest to lowest.
  7. Display only the name, course, and marks using $project.
  8. Find the two students with the highest fees.
  9. Build a pipeline that filters Java students and calculates their average fee.

Run the insertion command only once, or clear the test collection before inserting the same sample data again.

🧠 Quick Quiz

1. Which method runs an aggregation pipeline?




2. Which stage groups documents?




3. Which accumulator calculates an average?