MongoDB Query to Count by Group with Example
$group and $sum to count documents by group, like db.collection.aggregate([{ $group: { _id: "$field", count: { $sum: 1 } } }]).Examples
How to Think About It
$group to group by the field and $sum to add one for each document in that group.Algorithm
Code
db.collection.aggregate([
{ $group: { _id: "$category", count: { $sum: 1 } } }
])Dry Run
Let's trace counting documents by 'category' field in a collection with three documents.
Group documents by 'category'
Documents: [{category: 'fruit'}, {category: 'vegetable'}, {category: 'fruit'}] grouped into 'fruit' and 'vegetable'.
Count documents in each group
'fruit' group has 2 documents, 'vegetable' group has 1 document.
| Group (_id) | Count |
|---|---|
| fruit | 2 |
| vegetable | 1 |
Why This Works
Step 1: Grouping with $group
The $group stage collects documents sharing the same value in the specified field into one group.
Step 2: Counting with $sum
Inside $group, $sum: 1 adds 1 for each document in the group, effectively counting them.
Alternative Approaches
db.collection.aggregate([
{ $group: { _id: "$category" } },
{ $count: "totalGroups" }
])db.collection.mapReduce( function() { emit(this.category, 1); }, function(key, values) { return Array.sum(values); }, { out: "category_counts" } )
Complexity: O(n) time, O(k) space
Time Complexity
The aggregation scans all n documents once, grouping them by the field, so time is proportional to the number of documents.
Space Complexity
Space depends on the number of unique groups k, as it stores counts for each group.
Which Approach is Fastest?
Aggregation with $group is faster and more memory efficient than mapReduce for counting by group.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Aggregation $group + $sum | O(n) | O(k) | Counting documents by group efficiently |
| mapReduce | O(n) | O(k) | Complex processing but slower |
| Aggregation $count after $group | O(n) | O(1) | Counting number of groups, not documents |
$group and $sum for efficient counting by group.$sum: 1 inside $group results in no counts being calculated.