Ranjith
Ranjith

Reputation: 2819

Node.js - how to calculate the aggregate(sum) of sub document in mongodb?

My collection structure was,

[{
    "_id": "....",
    "name": "aaaa",
    "level_max_leaves": [{
        level: "ObjectIdString 1",
        max_leaves: 4,
    }]
}, {
    "_id": "....",
    "name": "bbbb",
    "level_max_leaves": [{
        level: "ObjectIdString 1",
        max_leaves: 4,
    }]
}, {
    "_id": "....",
    "name": "cccc",
    "level_max_leaves": [{
        level: "ObjectIdString 1",
        max_leaves: 7,
    }]
}, {
    "_id": "....",
    "name": "dddd",
    "level_max_leaves": [{
        level: "ObjectIdString 2",
        max_leaves: 3,
    }]
}]

Now I need to sum the field of max_leaves which has the ObjectIdString 1?

And the result of (4+4+7=15).

so far I tried

var empLevelId = 1234... ;
MyModel.aggregate(
    {$unwind: "$level_max_leaves.level"},
    {$match: {"$level_max_leaves.level": empLevelId } },
    {$group: { "_id": "$level_max_leaves.level", 
               "total": { "$sum": "$level_max_leaves.max_leaves" }}},
    function (err, res) {
        console.log(res);
});

How to achieve this?

Upvotes: 1

Views: 1632

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151112

Generally when dealing with arrays in the aggregation framework you need to $unwind the array contents first. This "de-normalizes" the content as individual documents. From here normal grouping operations work as expected:

MyModel.aggregate([

    // Unwind to "de-normalize"
    { "$unwind": "$level_max_leaves" },

    // Group as expected
    { "$group": {
        "_id": "$level_max_leaves.level",
        "total": { "$sum": "$level_max_leaves.max_leaves" }
    }}

],function(err,result) {

    // process results here

});

Note also that the "absolute" paths are required when addressing elements.

Upvotes: 2

Related Questions