8. Grouping Documents with $group
$group combines documents with the same _id group key and calculates values with accumulators. Use _id: null to create one overall summary, or a field or constructed document to group by one or multiple dimensions.
Common accumulators include $sum, $avg, $min, $max, $first, $last, $push, $addToSet, $stdDevPop, and $stdDevSamp. $first and $last depend on input order; sort first if chronological order matters.
Grouping can be expensive when many distinct keys are created. Be cautious about collecting very large arrays with $push, especially because result documents must remain within BSON size limits.
Grouping by customer produces customer summaries; grouping by status produces status summaries; grouping by both produces one summary for each combination.
db.orders.aggregate([
{ $match: { status: "delivered" } },
{
$set: {
itemSubtotal: {
$sum: {
$map: {
input: "$items",
as: "item",
in: { $multiply: ["$$item.quantity", "$$item.price"] }
}
}
}
}
},
{
$group: {
_id: "$customerId",
deliveredOrderCount: { $sum: 1 },
totalItemRevenue: { $sum: "$itemSubtotal" },
averageOrderSubtotal: { $avg: "$itemSubtotal" },
lowestOrderSubtotal: { $min: "$itemSubtotal" },
highestOrderSubtotal: { $max: "$itemSubtotal" }
}
},
{ $sort: { totalItemRevenue: -1, _id: 1 } }
]);- $group requires an _id key.
- Use _id: null for one overall summary.
- Accumulators calculate totals and summaries.
- Sort explicitly when $first or $last must be chronological.
Which configuration calculates one total across all input documents?