不是立即可见,但有可能。您在这里需要做的是将顶级文档与注释数组结合起来,而不是重复它。这是一种首先将内容作为两个数组连接成一个单一数组的方法,然后$unwind http://docs.mongodb.org/manual/reference/operator/aggregation/unwind/对内容进行分组:
db.collection.aggregate([
{ "$group": {
"_id": "$_id",
"author": {
"$addToSet": {
"id": "$_id",
"author": "$author",
"votes": "$votes"
}
},
"comments": { "$first": "$comments" }
}},
{ "$project": {
"combined": { "$setUnion": [ "$author", "$comments" ] }
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
给出输出:
{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }
即使跳过第一个$group http://docs.mongodb.org/manual/reference/operator/aggregation/group/阶段并以不同的方式制作组合数组:
db.collection.aggregate([
{ "$project": {
"combined": {
"$setUnion": [
{ "$map": {
"input": { "$literal": ["A"] },
"as": "el",
"in": {
"author": "$author",
"votes": "$votes"
}
}},
"$comments"
]
}
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
那些使用诸如$setUnion http://docs.mongodb.org/manual/reference/operator/aggregation/setUnion/乃至$map http://docs.mongodb.org/manual/reference/operator/aggregation/map/从 MongoDB 2.6 开始引入。这使得它更简单,但仍然可以在缺乏这些运算符的早期版本中完成,遵循大致相同的原则:
db.collection.aggregate([
{ "$project": {
"author": 1,
"votes": 1,
"comments": 1,
"type": { "$const": ["A","B"] }
}},
{ "$unwind": "$type" },
{ "$unwind": "$comments" },
{ "$group": {
"_id": {
"$cond": [
{ "$eq": [ "$type", "A" ] },
{
"id": "$_id",
"author": "$author",
"votes": "$votes"
},
"$comments"
]
}
}},
{ "$group": {
"_id": "$_id.author",
"votes": { "$sum": "$_id.votes" }
}},
{ "$sort": { "votes": -1 } }
])
The $const
未记录,但存在于存在聚合框架的所有 MongoDB 版本中(从 2.2 开始)。 MongoDB 2.6 推出$literal http://docs.mongodb.org/manual/reference/operator/aggregation/literal/它本质上链接到相同的底层代码。它在这里被用于两种情况,要么为数组提供模板元素,要么引入要展开的数组,以便在两个操作之间提供“二元选择”。