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?
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.