0
0
MongodbHow-ToBeginner · 2 min read

MongoDB Query to Find Distinct Values with Count

Use MongoDB's aggregation pipeline with $group to group by the field and count occurrences, like db.collection.aggregate([{ $group: { _id: "$field", count: { $sum: 1 } } }]) to get distinct values with their counts.
📋

Examples

Input[{ name: "Alice" }, { name: "Bob" }, { name: "Alice" }]
Output[{ _id: "Alice", count: 2 }, { _id: "Bob", count: 1 }]
Input[{ category: "Fruit" }, { category: "Vegetable" }, { category: "Fruit" }, { category: "Fruit" }]
Output[{ _id: "Fruit", count: 3 }, { _id: "Vegetable", count: 1 }]
Input[]
Output[]
🧠

How to Think About It

To find distinct values with their counts, think of grouping all documents by the field you want distinct values from, then count how many documents fall into each group. This is done by using $group in MongoDB aggregation, which collects documents by a key and can sum counts.
📐

Algorithm

1
Select the collection to query.
2
Group documents by the target field using <code>$group</code>.
3
For each group, count the number of documents using <code>$sum: 1</code>.
4
Return the grouped distinct values with their counts.
💻

Code

mongodb
db.collection.aggregate([
  { $group: { _id: "$field", count: { $sum: 1 } } }
])
Output
[ { _id: "value1", count: 5 }, { _id: "value2", count: 3 }, { _id: "value3", count: 2 } ]
🔍

Dry Run

Let's trace grouping and counting distinct values for field 'color' in sample documents.

1

Group by 'color'

Documents: [{color: 'red'}, {color: 'blue'}, {color: 'red'}, {color: 'green'}, {color: 'blue'}]

2

Count each group

Groups: 'red' -> 2, 'blue' -> 2, 'green' -> 1

colorcount
red2
blue2
green1
💡

Why This Works

Step 1: Grouping documents

The $group stage groups documents by the specified field, creating buckets for each distinct value.

Step 2: Counting documents per group

Using $sum: 1 adds 1 for each document in the group, giving the count of occurrences.

🔄

Alternative Approaches

Using distinct and then counting in application
mongodb
const distinctValues = await db.collection.distinct('field');
const counts = {};
for (const val of distinctValues) {
  counts[val] = await db.collection.countDocuments({ field: val });
}
console.log(counts);
This method requires multiple queries and is less efficient than aggregation.
Aggregation with $sortByCount
mongodb
db.collection.aggregate([
  { $sortByCount: "$field" }
])
<code>$sortByCount</code> is a shortcut for grouping and counting, returning distinct values with counts sorted by count.

Complexity: O(n) time, O(k) space

Time Complexity

The aggregation scans all documents once, so time is proportional to the number of documents, O(n).

Space Complexity

Space depends on the number of distinct values k, as groups are stored in memory, O(k).

Which Approach is Fastest?

Aggregation with $group or $sortByCount is faster and more efficient than multiple queries using distinct() and countDocuments().

ApproachTimeSpaceBest For
Aggregation with $groupO(n)O(k)Efficient counting of distinct values
Aggregation with $sortByCountO(n)O(k)Concise syntax with sorting by count
distinct() + countDocuments()O(n*k)O(k)Simple but inefficient for large data
💡
Use $sortByCount for a concise way to get distinct values with counts sorted by frequency.
⚠️
Trying to use distinct() alone to get counts, which only returns unique values without counts.