mongodb aggregation count items from two arrays

徘徊边缘 提交于 2019-12-13 06:48:35

问题


I'm trying to count the items from two arrays within the same model:

Model:

{_id:1
 name:"fun",
   objectsTypeA: [
        objectId_1
        objectId_2
   ],
   objectsTypeB: [
        objectId_5
        objectId_9
   ]
},
{_id:2
 name:"boring",
   objectsTypeA: [
        objectId_3
        objectId_4
   ],
   objectsTypeB: []
}

I'm trying to get the following result:

[
  { name:"fun",
    id: 1,
    count:4
  },
  { name:"boring",
    id: 2,
    count: 2
  ] 

What I got so far is this:

Object.aggregate([
       {$project: {_id:1, name:1, objectsTypeA:1}},
       {$unwind:'$objectsTypeA'},
       {$group: {
           _id: "$name",
    taggableId: {$addToSet:'$_id'},
         count: { $sum: 1}
       }},
   ], function(err, t){
      if (!err){
          res.jsonp(t);
      }
   });

This pretty much is what I want, but it only works for one of the two arrays from my model, I'm looking for some advice on how to reach that result, if it's actually possible.

Thanks in advance.


回答1:


Yes there certainly is a aggregate gotcha in here and that is if you attempt to unwind an empty array the results will be lost for it's parent record as it considers there is nothing there to unwind.

So right now the easiest way to solve this is with mapReduce:

db.objects.mapReduce(
    function () {
        emit(
            this._id,
            {
                "name": this.name,
                "count": this.objectsTypeA.length + this.objectsTypeB.length
            }
        );
     },
     function(){},
     { "out": { "inline": 1 } }
 )

In future versions of MongoDB there is a $size operator available to the aggregation pipeline, so you can simply do much the same with aggregate:

db.objects.aggregate([
    { "$project": {
        "name": 1,
        "count": { "$add": [ 
            { "$size": "$objectsTypeA" },
            { "$size": "$objectsTypeB" }
        ]}
    }}
])



回答2:


Since there are 2 arrays, you'd have to unwind both the arrays to get the count across both arrays. Try this:

Object.aggregate([
       {$project: {_id:1, name:1, objectsTypeA:1,  objectsTypeB:1}},
       {$unwind:'$objectsTypeA'},
       {$unwind:'$objectsTypeB'},
       {$group: {
           _id: "$name",
    taggableId: {$addToSet:'$_id'},
         count: { $sum: 1}
       }},
   ], function(err, t){
      if (!err){
          res.jsonp(t);
      }
   });


来源:https://stackoverflow.com/questions/22822483/mongodb-aggregation-count-items-from-two-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!