我的文档结构如下:
{"x":1, "y":1}
其中密钥未知且动态。我想要一个聚合所有字段的结果。 示例: 如果我的收藏包括:
{"x":1, "y":10}
{"x":1, "y":20}
{"x":2 , "z":13}
我希望结果是
{"sum":{"x":4, "y":30,"z":13}
这怎么可能?
答案 0 :(得分:2)
使用MongoDB 3.6,您可以使用$objectToArray
和$arrayToObject
将对象拆分并累积:
db.collection.aggregate([
{ "$project": {
"data": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"cond": { "$ne": [ "$$this.k", "_id" ] }
}
}
}},
{ "$unwind": "$data" },
{ "$group": {
"_id": "$data.k",
"v": { "$sum": "$data.v" }
}},
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": null,
"data": { "$push": { "k": "$_id", "v": "$v" } }
}},
{ "$replaceRoot": {
"newRoot": { "$arrayToObject": "$data" }
}}
])
返回:
{ "x" : 4, "y" : 30, "z" : 13 }
如果您没有支持这些运营商的MongoDB,基本上与mapReduce()
相同:
db.collection.mapReduce(
function() {
var doc = this;
delete doc._id;
emit(null, doc);
},
function(key,values) {
var output = {};
values.forEach(value =>
Object.keys(value).forEach(k => {
if (!output.hasOwnProperty(k))
output[k] = 0;
output[k] = output[k] + value[k];
})
);
return output;
},
{ "out": { "inline": 1 } }
)
略有不同,mapReduce样式输出:
{
"_id" : null,
"value" : {
"x" : 4,
"y" : 30,
"z" : 13
}
}