$group
The $group stage aggregates documents by a specified _id expression and applies accumulator operations to grouped documents.
📌 Syntax
{
"$group": {
"_id": <expression>,
"field1": { "<accumulator>": <expression> },
...
}
}
📦 Ecommerce Example – Total Sales and Item Count per Category
{
"$group": {
"_id": "$category",
"totalSales": { "$sum": "$price" },
"itemCount": { "$sum": 1 }
}
}
Input Documents
[
{ "product": "Laptop", "category": "Electronics", "price": 900 },
{ "product": "Phone", "category": "Electronics", "price": 600 },
{ "product": "Shoes", "category": "Fashion", "price": 75 },
{ "product": "Book", "category": "Books", "price": 20 }
]
Output Documents
[
{ "_id": "Electronics", "totalSales": 1500, "itemCount": 2 },
{ "_id": "Fashion", "totalSales": 75, "itemCount": 1 },
{ "_id": "Books", "totalSales": 20, "itemCount": 1 }
]
🔁 Group by Composite Keys
{
"$group": {
"_id": { "category": "$category", "brand": "$brand" },
"count": { "$sum": 1 }
}
}
➕ Supported Accumulators
| Accumulator | Description |
|---|---|
$sum |
Total or count |
$avg |
Average value |
$min / $max |
Extremes |
$push |
Array of values |
$addToSet |
Unique values |
$first / $last |
First/last by input order |
🎯 Ecommerce Accumulator Examples
{
"$group": {
"_id": "$category",
"avgPrice": { "$avg": "$price" },
"minPrice": { "$min": "$price" },
"maxPrice": { "$max": "$price" },
"allBrands": { "$push": "$brand" },
"uniqueBrands": { "$addToSet": "$brand" },
"firstItem": { "$first": "$product" },
"lastItem": { "$last": "$product" }
}
}
🔧 Operators in Expressions
Operators may appear in _id and value expressions.
| Operator | Example |
|---|---|
$toUpper |
{ "$toUpper": "$category" } |
$cond |
{ "$cond": { "if": ..., "then": ..., "else": ... } } |
$convert |
Convert field to number or string |
$multiply |
Pre-process price with quantity |
Example – Group by Uppercase Category and Conditional Total
{
"$group": {
"_id": { "$toUpper": "$category" },
"total": {
"$sum": {
"$cond": {
"if": { "$gte": ["$price", 100] },
"then": "$price",
"else": 0
}
}
}
}
}
✅ Best Practices
- Use
$sum: 1to count documents - Use
$condor$mapto pre-process values - Output field names can differ from input fields