聚合的单一形式:
db.tags.aggregate([
{ "$project": {
"_id": 0,
"t1": 1,
"t2": 2,
"type": { "$literal": ["t1","t2"] }
}},
{ "$unwind": "$type" },
{ "$project": {
"type": 1,
"value": {
"$cond": [
{ "$eq": [ "$type", "t1" ] },
"$t1",
"$t2"
]
}
}},
{ "$unwind": "$value" },
{ "$group": {
"_id": {
"type": "$type",
"value": "$value"
},
"count": { "$sum": 1 }
}},
{ "$sort": { "_id.type": 1, "_id.value": 1 } }
])
然后输出:
{ "_id" : { "type" : "t1", "value" : 1 }, "count" : 2 }
{ "_id" : { "type" : "t1", "value" : 2 }, "count" : 1 }
{ "_id" : { "type" : "t1", "value" : 3 }, "count" : 1 }
{ "_id" : { "type" : "t1", "value" : 6 }, "count" : 2 }
{ "_id" : { "type" : "t2", "value" : 1 }, "count" : 1 }
{ "_id" : { "type" : "t2", "value" : 8 }, "count" : 3 }
{ "_id" : { "type" : "t2", "value" : 9 }, "count" : 1 }
或者,如果您更喜欢单个文档,只需将结束阶段替换为 $group 和 $project:
{ "$group": {
"_id": null,
"t1": {
"$push": {
"$cond": [
{ "$eq": [ "$_id.type", "t1" ] },
{ "value": "$_id.value", "count": "$count" },
false
]
}
},
"t2": {
"$push": {
"$cond": [
{ "$eq": [ "$_id.type", "t2" ] },
{ "value": "$_id.value", "count": "$count" },
false
]
}
},
}},
{ "$project": {
"_id": 0,
"t1": { "$setDifference": [ "$t1", [false] ] },
"t2": { "$setDifference": [ "$t2", [false] ] }
}}
结果:
{
"t1" : [
{ "value" : 2, "count" : 1 },
{ "value" : 6, "count" : 2 },
{ "value" : 3, "count" : 1 },
{ "value" : 1, "count" : 2 }
],
"t2" : [
{ "value" : 1, "count" : 1 },
{ "value" : 9, "count" : 1 },
{ "value" : 8, "count" : 3 }
]
}
在不使用 MongoDB 2.6 中的新运算符的情况下,这些都是可能的,只是需要更多的工作。
mapReduce 方法看起来相当简单。由于 mapReduce 的限制,输出当然不是您的格式,但它无需迭代查询即可获得结果:
db.collection.mapReduce(
function () {
delete this["_id"];
for ( var k in this ) {
var list = this[k];
list.forEach(function(v) {
emit( { k: k , v: v }, 1 );
});
}
},
function (key,values) {
return values.length;
},
{ "out": { "inline": 1 } }
)
输出将是:
{ "_id" : { "k" : "t1", "v" : 1 }, "value" : 2 }
{ "_id" : { "k" : "t1", "v" : 2 }, "value" : 1 }
{ "_id" : { "k" : "t1", "v" : 3 }, "value" : 1 }
{ "_id" : { "k" : "t1", "v" : 6 }, "value" : 2 }
{ "_id" : { "k" : "t2", "v" : 1 }, "value" : 1 }
{ "_id" : { "k" : "t2", "v" : 8 }, "value" : 3 }
{ "_id" : { "k" : "t2", "v" : 9 }, "value" : 1 }
还取决于您是否需要灵活使用“关键”名称。