Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group by subdocument field using aggregation framework

The structure is the following:

{
    "_id" : "79f00e2f-5ff6-42e9-a341-3d50410168de",
    "bookings" : [
        {
            "name" : "name1",
            "email" : "[email protected]",
            "startDate" : ISODate("2013-12-31T22:00:00Z"),
            "endDate" : ISODate("2014-01-09T22:00:00Z")
        },
        {
            "name" : "name2",
            "email" : "[email protected]",
            "startDate" : ISODate("2014-01-19T22:00:00Z"),
            "endDate" : ISODate("2014-01-24T22:00:00Z")
        }
    ],
    "name" : "Hotel0",
    "price" : 0,
    "rating" : 2 
}

Now, I want to generate a report telling me how many bookings were made, grouped by booking month (assume that only booking start date matters) and also grouped by hotels rating.

I expect the answer to be like that:

{
    {
        rating: 0,
        counts: {
            month1: 10,
            month2: 20,
            ...
            month12: 7
        }
    }
    {
        rating: 1,
        counts: {
            month1: 5,
            month2: 8,
            ...
            month12: 9
        }
    }
    ...
    {
        rating: 6,
        counts: {
            month1: 22,
            month2: 23,
            ...
            month12: 24
        }
    }
}

I tried this with aggregation framework but I'm a little bit stuck.

like image 374
grozandrei Avatar asked Jan 09 '14 16:01

grozandrei


People also ask

How can you group by a particular value in MongoDB?

We can group by single as well as multiple field from the collection, we can use $group operator in MongoDB to group fields from the collection and returns the new document as result. We are using $avg, $sum, $max, $min, $push, $last, $first and $addToSet operator with group by in MongoDB.

Which command is correct for grouping a set of documents by the field?

The $group stage separates documents into groups according to a "group key". The output is one document for each unique group key.

Which functionality is used for aggregation framework?

8. Which of the following functionality is used for aggregation framework? Explanation: For related projection functionality in the aggregation framework pipeline, use the $project pipeline stage.

How do I group multiple fields in MongoDB?

One of the most efficient ways of grouping the various fields present inside the documents of MongoDB is by using the $group operator, which helps in performing multiple other aggregation functions as well on the grouped data.


1 Answers

The following query:

db.book.aggregate([
    { $unwind: '$bookings' },
    { $project: { bookings: 1, rating: 1, month: { $month: '$bookings.startDate' } } },
    { $group: { _id: { rating: '$rating', month: '$month' }, count: { $sum: 1 } } }
]);

Will give you the result per rating/month, but it does not make a subdocument for months. In general, you can not convert a value (such as the month nr) to a key (such as month1)—this is something you can probably quite easily handle in your application though.

The above aggregation results in:

"result" : [
    {
        "_id" : {
            "rating" : 2,
            "month" : 1
        },
        "count" : 1
    },
    {
        "_id" : {
            "rating" : 2,
            "month" : 12
        },
        "count" : 1
    }
],
"ok" : 1
like image 148
Derick Avatar answered Sep 19 '22 18:09

Derick