问题
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