我正在尝试计算同一模型中两个数组中的项目:
型:
{_id:1
name:"fun",
objectsTypeA: [
objectId_1
objectId_2
],
objectsTypeB: [
objectId_5
objectId_9
]
},
{_id:2
name:"boring",
objectsTypeA: [
objectId_3
objectId_4
],
objectsTypeB: []
}
我正在尝试获得以下结果:
[
{ name:"fun",
id: 1,
count:4
},
{ name:"boring",
id: 2,
count: 2
]
到目前为止,我得到的是这样的:
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);
}
});
这几乎是我想要的,但它仅适用于我的模型中的两个数组之一,如果真的可能的话,我正在寻找一些关于如何达到该结果的建议。
提前谢谢。
是的,这里肯定有一个aggregate
问题,那就是如果您尝试展开一个空数组,则其父记录的结果将丢失,因为它认为没有什么可以展开的。
所以现在解决这个问题的最简单方法是使用 mapReduce
:
db.objects.mapReduce(
function () {
emit(
this._id,
{
"name": this.name,
"count": this.objectsTypeA.length + this.objectsTypeB.length
}
);
},
function(){},
{ "out": { "inline": 1 } }
)
在MongoDB的未来版本中,有一个$size
运算符可用于聚合管道,因此您可以简单地对聚合执行相同的操作:
db.objects.aggregate([
{ "$project": {
"name": 1,
"count": { "$add": [
{ "$size": "$objectsTypeA" },
{ "$size": "$objectsTypeB" }
]}
}}
])
由于有 2 个数组,因此您必须unwind
两个数组才能获得两个数组的计数。 试试这个:
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);
}
});