Given the following record in my MongoDB table:
{
\"_id\" : ObjectId(\"5a00c1c71680084c55811ae2\"),
\"name\" : \"test\",
\"tenantId\" : \"paul\",
Actually you can simply do:
db.table.aggregate( [
{ "$match" : { "tenantId": "paul" } },
//{ $unwind:{ path: "$deposits", preserveNullAndEmptyArrays: true }},
{ "$project":
"deposits": { "$subtract": ["$price", { "$sum": "$deposits.amount" } ] }
}}
])
Since MongoDB 3.2 you can actually $project with $sum and an array of arguments ( or an array ) and therefore do not need to $unwind at all.
Changed in version 3.2: $sum is available in the $group and $project stages. In previous versions of MongoDB, $sum is available in the $group stage only.
When used in the $project stage, $sum returns the sum of the specified expression or list of expressions for each document ...
The "long" way, which is the "old" way is to actually use $unwind, but you would then actually add a $project following the $group:
db.table.aggregate( [
{ "$match" : { "tenantId": "paul" } },
{ $unwind:{ path: "$deposits", preserveNullAndEmptyArrays: true }},
{ "$group":
"_id": "$_id",
"price": { "$first": "$price" },
"deposits": { "$sum": "$deposits.amount" }
}},
{ "$project": {
"deposits": { "$subtract": [ "$price", "$deposits" ] }
}}
])
And of course you then need the $first accumulator in order to return the "price" field from the $group stage so it can be used in the following stage.
But if you can do preserveNullAndEmptyArrays, then you actually have MongoDB 3.2, and therefore are better off using the statement without the $unwind at all, since it's much faster to do it that way.