Mongodb Query, search array elements inside document grouping by and counting each element

Luis Miguel :

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.

user2683814 :

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"}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=108252&siteId=1