MongoDB group Stage
The $group stage collapses many documents into one document per distinct key, letting you compute sums, averages, counts, and other aggregates for each group.
The Anatomy of $group
A $group stage always specifies an _id field, which defines the grouping key, plus any number of accumulator fields that compute a value across all documents sharing that key. If you set _id to null, every document in the pipeline collapses into a single group, which is useful for computing an overall total or average across an entire collection.
Grouping by a Single Field
db.orders.aggregate([
{ $group: {
_id: "$customerId",
totalSpent: { $sum: "$amount" },
orderCount: { $sum: 1 }
} }
])Common Accumulator Operators
MongoDB ships with a full set of accumulator operators you can use inside $group. $sum adds numeric values across the group, $avg computes a mean, $min and $max find extremes, $push collects every value into an array, and $addToSet does the same but discards duplicates. You can combine several accumulators in the same $group stage to compute multiple statistics in a single pass.
- $sum: adds a field's value, or increment by 1 for a plain count
- $avg: computes the arithmetic mean across the group
- $min / $max: returns the smallest or largest value seen
- $push: builds an array containing every value in the group
- $addToSet: builds an array of unique values only
- $first / $last: grabs the value from the first or last document in each group as it arrives
Grouping by a Compound Key
db.sales.aggregate([
{ $group: {
_id: { region: "$region", year: "$year" },
totalRevenue: { $sum: "$amount" },
avgOrderValue: { $avg: "$amount" },
products: { $addToSet: "$product" }
} },
{ $sort: { "_id.year": 1, totalRevenue: -1 } }
])Using an object as _id lets you group by more than one field at once. The resulting documents carry a nested _id containing region and year, so downstream stages like $sort need to reference _id.year and _id.region using dot notation.
Grouping Everything Into One Document
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: {
_id: null,
grandTotal: { $sum: "$amount" },
averageOrder: { $avg: "$amount" },
largestOrder: { $max: "$amount" }
} }
])