Group and count by month

Solution 1:

You need to use the $month keyword in your group. Your new Date().getMonth() call will only happen once, and will try and create a month out of the string "$bookingdatetime".

db.booking.aggregate([
    {$group: {
        _id: {$month: "$bookingdatetime"}, 
        numberofbookings: {$sum: 1} 
    }}
]);

Solution 2:

You can't include arbitrary JavaScript in your aggregation pipeline, so because you're storing bookingdatetime as a string instead of a Date you can't use the $month operator.

However, because your date strings follow a strict format, you can use the $substr operator to extract the month value from the string:

db.test.aggregate([
    {$group: {
        _id: {$substr: ['$bookingdatetime', 5, 2]}, 
        numberofbookings: {$sum: 1}
    }}
])

Outputs:

{
    "result" : [ 
        {
            "_id" : "03",
            "numberofbookings" : 1
        }, 
        {
            "_id" : "07",
            "numberofbookings" : 1
        }, 
        {
            "_id" : "10",
            "numberofbookings" : 1
        }
    ],
    "ok" : 1
}

Solution 3:

Starting in Mongo 4, you can use the $toDate operator to convert your string to date (building on the answer given by Will Shaver):

// { date: "2012-10-11T07:00:00Z" }
// { date: "2012-10-23T18:30:00Z" }
// { date: "2012-11-02T21:30:00Z" }
db.bookings.aggregate([
  { $group: {
    _id: { month: { $month: { $toDate: "$date" } } },
    bookings: { $sum: 1 }
  }}
])
// { "_id" : { "month" : 10 }, "bookings" : 2 }
// { "_id" : { "month" : 11 }, "bookings" : 1 }