我有一个MongoDB集合,其中的文档格式为:
{
year: 1900,
alabama: 145,
arkansas: 103,
// ... for all 50 US states
}
我想要一个查询,给出每个州的集合总和。结果可能如下:
{
alabama: 1360492,
arkansas: 598023,
// ... and so on
}
我能想到的最好的是一个包含50个术语的聚合查询:
db.sample.aggregate({$group: {
_id: "",
alabama: {$sum: "$alabama"},
arkansas: {$sum: "$arkansas"},
// ... and so on
}});
有没有办法构建查询,允许我只提供需要求和的字段名数组?
答案 0 :(得分:4)
我不知道使用聚合框架的方法,但使用mapreduce,它是相当直接的;
> db.test.insert({ year: 1900, alabama: 145, arkansas: 103 })
> db.test.insert({ year: 1901, alabama: 100, arkansas: 77 })
// Map function, emits the state name and the value for each entry
> var m = function () {
for(var key in this) {
if(this.hasOwnProperty(key) &&
key != 'year' && key!='_id')
emit(key, this[key])
}
}
// Reduce function, just sums up the score per state
> var r = function (state, score) { return Array.sum(score); }
// Run mapreduce with map function m, reduce function r, and output inline
> db.test.mapReduce(m, r, {out:{inline:1}})
{
"results" : [
{
"_id" : "alabama",
"value" : 245
},
{
"_id" : "arkansas",
"value" : 180
}
]
}
编辑:为了能够使用聚合框架,我无法看到一种方法,只需稍微改变数据模型就可以作为密钥访问状态;
> db.test2.insert({ year: 1900, data:[{k:"alabama", v:145},
{k:"arkansas", v:103}] } )
> db.test2.insert({ year: 1901, data:[{k:"alabama", v:100},
{k:"arkansas", v:77}] } )
// Unwind data, and group it back together by key while summing the values;
> db.test2.aggregate({$unwind:"$data"},
{$group:{_id:"$data.k",total:{$sum: "$data.v"}}})
{ "_id" : "arkansas", "total" : 180 }
{ "_id" : "alabama", "total" : 245 }