Suppose I have a collection with multiple documents with the following structure:
{
_id: "id12345",
objects: ["123","456", "789"]
}
Now I want to create a query where I pass an array of objects and get the count of occurrence in documents for each of the elements of the array, something like this:
input of query: ["123","321"]
output:
{
"123": 1,
"321": 0
}
I want to do this just by one query, passing an array, I know I could do this easily one by one instead of an array but that is not the purpose.
You can use below aggregation in 3.6.
$match
to filter documents where there is at least one array match between input array and objects array.
$project
with $map
to iterate the input array and compare with each array element in objects array and return 0 and 1 depending on the match.
$unwind
with $group
to count the occurrences of array element across all documents.
db.colname.aggregate([
{"$match":{"objects":{"$in":["123","321"]}}},
{"$project":{
"keyandcount":{
"$map":{
"input":["123","321"],
"in":{
"k":"$$this",
"v":{"$cond":[{"$in":["$$this","$objects"]},1,0]}
}
}
}
}},
{"$unwind":"$keyandcount"},
{"$group":{"_id":"$keyandcount.k","count":{"$sum":"$keyandcount.v"}}}
])
You can add below two stages at the end to format the response to key value pair.
{"$group":{_id: null,"keycountpair":{"$mergeObjects":{"$arrayToObject":[[["$_id","$count"]]]}}}},
{"$replaceRoot":{"newRoot":"$keycountpair"}}