MongoDB Query to Group Documents by Date
Use the MongoDB aggregation pipeline with
$group and extract the date part using $dateToString, like { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, count: { $sum: 1 } } } to group documents by date.Examples
Input[{ "date": ISODate("2024-06-01T10:00:00Z") }, { "date": ISODate("2024-06-01T15:00:00Z") }, { "date": ISODate("2024-06-02T09:00:00Z") }]
Output[{ "_id": "2024-06-01", "count": 2 }, { "_id": "2024-06-02", "count": 1 }]
Input[{ "date": ISODate("2024-06-03T00:00:00Z") }, { "date": ISODate("2024-06-03T23:59:59Z") }]
Output[{ "_id": "2024-06-03", "count": 2 }]
Input[]
Output[]
How to Think About It
To group documents by date, first extract only the date part (year, month, day) from the full timestamp. Then use
$group to collect documents sharing the same date. This way, you count or aggregate data per day, ignoring time details.Algorithm
1
Get the collection of documents with date fields.2
Use an aggregation pipeline to process documents.3
Extract the date part (year-month-day) from each document's date field.4
Group documents by this extracted date.5
Calculate the count or other aggregates for each date group.6
Return the grouped results.Code
mongodb
db.collection.aggregate([
{
$group: {
_id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
count: { $sum: 1 }
}
}
])Output
[
{ "_id": "2024-06-01", "count": 2 },
{ "_id": "2024-06-02", "count": 1 }
]
Dry Run
Let's trace grouping three documents by their date field.
1
Extract date string
Convert ISODate("2024-06-01T10:00:00Z") to "2024-06-01"
2
Group by date string
Group documents with _id "2024-06-01" and count how many fall into this group
3
Output grouped counts
Return array with counts per date string
| Date String | Count |
|---|---|
| 2024-06-01 | 2 |
| 2024-06-02 | 1 |
Why This Works
Step 1: Extract date part
The $dateToString operator formats the full date to just year-month-day, removing time.
Step 2: Group documents
The $group stage groups documents by the extracted date string as the key.
Step 3: Count documents
The $sum: 1 counts how many documents belong to each date group.
Alternative Approaches
Group by year, month, day fields separately
mongodb
db.collection.aggregate([
{
$group: {
_id: {
year: { $year: "$date" },
month: { $month: "$date" },
day: { $dayOfMonth: "$date" }
},
count: { $sum: 1 }
}
}
])This groups by separate fields instead of a formatted string, useful if you want to keep date parts separate.
Use $project to add a date string field first
mongodb
db.collection.aggregate([
{
$project: {
dateOnly: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }
}
},
{
$group: {
_id: "$dateOnly",
count: { $sum: 1 }
}
}
])This separates date extraction and grouping into two stages, which can improve readability.
Complexity: O(n) time, O(k) space
Time Complexity
The aggregation scans all n documents once, grouping them by date, so time is O(n).
Space Complexity
Space depends on k, the number of unique dates, to store grouped results.
Which Approach is Fastest?
Using $dateToString in $group is concise and efficient; separating with $project may be clearer but slightly slower.
| Approach | Time | Space | Best For |
|---|---|---|---|
| $group with $dateToString | O(n) | O(k) | Simple date grouping |
| Group by year, month, day fields | O(n) | O(k) | When separate date parts needed |
| $project then $group | O(n) | O(k) | Readability and stepwise processing |
Use
$dateToString to convert dates to a consistent string format before grouping.Forgetting to extract only the date part causes grouping by full timestamp, resulting in many groups with single documents.