0
0
MongodbHow-ToBeginner · 2 min read

MongoDB Query to Group Documents by Month

Use the MongoDB aggregation pipeline with $group and extract the month using $month from a date field like { $group: { _id: { month: { $month: "$date" } }, count: { $sum: 1 } } } to group documents by month.
📋

Examples

Input[{ "date": ISODate("2023-01-15T00:00:00Z") }, { "date": ISODate("2023-01-20T00:00:00Z") }, { "date": ISODate("2023-02-10T00:00:00Z") }]
Output[{ "_id": { "month": 1 }, "count": 2 }, { "_id": { "month": 2 }, "count": 1 }]
Input[{ "date": ISODate("2023-12-01T00:00:00Z") }, { "date": ISODate("2023-12-15T00:00:00Z") }, { "date": ISODate("2023-11-30T00:00:00Z") }]
Output[{ "_id": { "month": 11 }, "count": 1 }, { "_id": { "month": 12 }, "count": 2 }]
Input[]
Output[]
🧠

How to Think About It

To group documents by month, first extract the month number from the date field using $month. Then use $group to collect documents sharing the same month and count them. This groups all entries by their month value.
📐

Algorithm

1
Get the collection of documents with a date field.
2
Extract the month number from each document's date using <code>$month</code>.
3
Group documents by this month number using <code>$group</code>.
4
Count the number of documents in each group.
5
Return the grouped results with month and count.
💻

Code

mongodb
db.collection.aggregate([
  {
    $group: {
      _id: { month: { $month: "$date" } },
      count: { $sum: 1 }
    }
  }
])
Output
[ { "_id": { "month": 1 }, "count": 2 }, { "_id": { "month": 2 }, "count": 1 } ]
🔍

Dry Run

Let's trace grouping three documents by month using their date field.

1

Extract month from each date

Dates: 2023-01-15, 2023-01-20, 2023-02-10 → Months: 1, 1, 2

2

Group documents by month

Group 1: two documents, Group 2: one document

3

Count documents in each group

Month 1 count: 2, Month 2 count: 1

MonthCount
12
21
💡

Why This Works

Step 1: Extract month using $month

The $month operator pulls the month number (1-12) from each document's date field.

Step 2: Group by month with $group

The $group stage collects documents sharing the same month into one group.

Step 3: Count documents in each group

Using $sum: 1 counts how many documents fall into each month group.

🔄

Alternative Approaches

Group by year and month
mongodb
db.collection.aggregate([
  {
    $group: {
      _id: {
        year: { $year: "$date" },
        month: { $month: "$date" }
      },
      count: { $sum: 1 }
    }
  }
])
Groups by both year and month to separate same months in different years.
Group by formatted month string
mongodb
db.collection.aggregate([
  {
    $group: {
      _id: { $dateToString: { format: "%Y-%m", date: "$date" } },
      count: { $sum: 1 }
    }
  }
])
Groups by year-month string for readable output but slightly slower.

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

Time Complexity

The aggregation scans all n documents once to extract months and group them, so it is O(n).

Space Complexity

It uses extra space proportional to the number of unique months k, so O(k).

Which Approach is Fastest?

Grouping by numeric month is fastest; grouping by formatted strings is slower due to string operations.

ApproachTimeSpaceBest For
Group by $monthO(n)O(k)Simple month grouping
Group by year and monthO(n)O(k)Distinguishing months across years
Group by formatted stringO(n)O(k)Readable year-month output
💡
Always ensure your date field is stored as a proper Date type for $month to work correctly.
⚠️
Trying to group by month on a string date without converting it to a Date type causes errors or wrong results.