首页 文章

如何在MongoDB集合中总结许多键

提问于
浏览
2

我有一个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
}});

有没有办法构建允许我只提供需要求和的字段名称数组的查询?

1 回答

  • 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 }
    

相关问题