I have a collection of entities like:
"_id" : ObjectId("123b1c231c4a460005dc658r"),
"unitId" : "58bd51815744bf06e001b57b",
"name" : "Main",
"shortName" : "Main",
"controlOperator" : "admin"
I have logins ["admin", "noAdmin", "john", "jack"] and I need to count:
admin : 10
noAdmin : 15
john : 0
jack : 14
I try
db
.getCollection('appeals')
.aggregate([
{$match: {$or: [{unitId: "58bd51815744bf06e001b57b", controlOperator: {$in: ["admin", "noAdmin", "john", "jack"]}}, {unitId: "58bd51815744bf06e001b57b", controlOperator: {$nin: ["admin", "noAdmin", "john", "jack"]}}]}},
{$project: {_id: 0}},
{$group: {_id: "$controlOperator", appeals: {$push: "$controlOperator"},
count: {$sum: 1}}}])
But I get only matched value:
admin : 10
noAdmin : 15
jack : 14
2
Answers
Query1
*alternative you can keep your group, and add the zero count fields if they are missing, or add them on the client with application code
Playmongo
Query2
operator:count
(you can create this with javascript)
Playmongo
Consider this highly condensed version of docs supplied by the OP:
Here is a way to get the desired output:
OPINION: This seems like a lot of work considering the client knows the full ops list and can do this:
Finally: there is potentially a cool use of
$setUnion
here by taking the ops targets, changing them into a "default" set of{op:name, N:0}
objects, and then merging the calculated results on top. Those targets with no group will remain asN:0
. I cannot get$setUnion
to work against sets of objects though, only scalars.