If you are new to using the aggregation framework commands you might not yet be aware of the $cond
operator. You can use this in order to get your totals separated:
db.collection.aggregate([
// Unwind the array to de-normalize the items
{ "$unwind": "$budgets" },
// Group the totals with conditions
{ "$group": {
"_id": "$_id",
"expense": { "$sum": {
"$cond": [
"$budgets.expense",
"$budgets.value",
0
]
}},
"nonExpense": { "$sum": {
"$cond": [
"$budgets.expense",
0,
"$budgets.value"
]
}}
}}
])
So what that will do is evaluate the true/false
condition of expense as the first argument, and when the condition is actually true
then the second argument of the $cond
will be chosen and passed on to the $sum
. If the condition evaluates to false
then the second argument is chosen.
But looking at your data you appear to have a problem:
{
"name" : "check",
"value" : "1000",
"expense" : "false",
"uniqueId" : 0.9880268634296954
},
Noting here that all of the fields, and most notably the expense
and value
items, are all strings. So this is a problem as while we could get around evaluating the true/false
values by doing string comparisons rather than direct boolean, you simply cannot co-erce a string as a number that can be passed to $sum
.
So firstly you need to fix your data, unless it is not actually in the form as you have represented. But when it meets a correct form, then you can do your aggregation.