MongoDB $group and accumulators
$group with $sum, $avg, $min, $max, $push, $addToSet. Β· 11 practice questions Β· Cheat sheet β
$group collapses many documents into one per key. _id is the grouping key, which can be a field ("$borough"), a compound object, or null for a single total. Every other output field is an accumulator: $sum (with $sum: 1 for a count), $avg, $min, $max, $push to collect values into an array, $addToSet for unique values, $first and $last for the edge documents of a sorted group.
The classic MongoDB $group by count example is { $group: { _id: "$borough", count: { $sum: 1 } } }, usually followed by { $sort: { count: -1 } }. The surprise for SQL users is that $group keeps nothing it was not told to keep: fields that are not the key or an accumulator vanish. If you need them, accumulate them with $first or $push, or group later in the pipeline.
MongoDB $group practice questions
- Count the restaurants in each
borough. Output the borough as_idand the count ascount. easy restaurants - Count restaurants per
cuisineascount, sorted from most to least. Break ties by cuisine name ascending. easy restaurants - For each
boroughcompute the average number ofseatsasavgSeats. medium restaurants - For each
boroughreturn the largest and smallestseatsvalues asmaxSeatsandminSeats. medium restaurants - For each
cuisinecollect the restaurant names into an array field callednames. medium restaurants - For each
boroughcollect the DISTINCT cuisines served into an array fieldcuisines. medium restaurants - Compute total revenue per customer: group
ordersbycustomerIdand sumtotalintorevenue. medium orders - Count restaurants for each combination of
cuisineandborough. The_idshould be an object with both keys. hard restaurants - Count orders by
statusasn, but only for orders placed through thewebchannel. hard orders - Compute the overall average
seatsacross the whole collection asavgSeats, in one group with_idof null. hard restaurants - For each
deptreturn the total salary bill aspayrolland the headcount asheadcount, sorted by payroll descending. hard employees
Each question is answered in a live mongo-shell editor on this page; the result is checked against a reference solution.
$group and accumulators cheat sheet
The shape
{ $group: {
_id: "$borough", // what to group by
count: { $sum: 1 }, // accumulators
avgSeats: { $avg: "$seats" }
} }
_id is mandatory. _id: null groups everything into one bucket.
Accumulators
| Accumulator | Does |
|---|---|
{ $sum: 1 } | counts documents |
{ $sum: "$total" } | adds a field up |
{ $avg: "$seats" } | mean |
{ $min: } / { $max: } | extremes |
{ $push: "$name" } | array of every value |
{ $addToSet: "$cuisine" } | array of distinct values |
{ $first: } / { $last: } | needs a $sort before it to mean anything |
Compound grouping key
{ $group: { _id: { cuisine: "$cuisine", borough: "$borough" }, n: { $sum: 1 } } }
Sort after grouping
{ $group: { _id: "$cuisine", n: { $sum: 1 } } },
{ $sort: { n: -1 } },
{ $limit: 5 }
Sorting before $group does not survive the group β regroup, then sort.
Gotchas
- After
$group, only the fields you declared exist.nameis gone unless
you pushed or $first-ed it.
$avgskips non-numeric and missing values rather than treating them as 0.
Common questions
How do I count documents per group in MongoDB?
{ $group: { _id: "$cuisine", count: { $sum: 1 } } }. Add { $sort: { count: -1 } } for most-to-least. { $sortByCount: "$cuisine" } does both in one stage.Why does $group lose my other fields?
$group builds brand-new documents from the key and the accumulators you list; nothing else survives. Keep a field with $first: "$name" (the first in the group's order), collect all values with $push, or move the $group later in the pipeline.What's the difference between $push and $addToSet?
$push keeps every value, including duplicates, in encounter order. $addToSet keeps each distinct value once, with no guaranteed order. Use $addToSet for "which cuisines appear in this borough".Continue:β Aggregation Basics$unwind & Array Pipelines β
MongoDB topics:Finding & ProjectionComparison OperatorsLogical OperatorsElement & TypePattern MatchingSort, Limit & SkipArray QueriesEmbedded DocumentsAggregation Basics$unwind & Array PipelinesJoins & Advanced StagesFull cheat sheet