Combustible Pizza
Combustible Pizza

Reputation: 325

MongoDB aggregation, distinct several fields and count them

The best way I can describe what I want to achieve is using an example. Basically I would have a list of cars say:

[
    {
        _id: 1,
        make: 'Toyota',
        model: 'Prius'
    },
    {
        _id: 2,
        make: 'Toyota',
        model: 'Prius'
    },
    {
        _id: 3,
        make: 'Toyota',
        model: 'Yaris'
    },
    {
        _id: 4,
        make: 'Lexus',
        model: 'RX400'
    }
]

And now I want to group/distinct them by make and model (and possibly more fields) and count the totals. The final result should look something like:

{
    makes: [
        {
            name: 'Toyota',
            total: 3
        }, {
            name: 'Lexus',
            total: 1
        }
    ],
    models: [
        {
            name: 'Prius',
            total: 2
        },
        {
            name: 'Yaris',
            total: 1
        },
        {
            name: 'RX400',
            total: 1
        }
    ]
}

I'm completely stuck with this one. So far, the only way I can achieve this is by calling several async aggregation calls for each field. However, I would prefer to do it in a single aggregation call, if that is possible at all (unless it's not a good idea performance wise).

Upvotes: 0

Views: 454

Answers (1)

chridam
chridam

Reputation: 103445

Use $facet for this:

db.collection.aggregate([
    { "$facet": {
        "makes": [
            { "$group": {
                "_id": "$make",
                "total": { "$sum": 1 }
            } },
            { "$project": {
                "_id": 0,
                "name": "$_id",
                "total": 1
            } }  
        ],
        "models": [
            { "$group": {
                "_id": "$model",
                "total": { "$sum": 1 }
            } },
            { "$project": {
                "_id": 0,
                "name": "$_id",
                "total": 1
            } }  
        ]
    } }
])

Upvotes: 2

Related Questions