Mongodb组按键

时间:2013-05-28 10:08:44

标签: mongodb

我有以下记录集作为查找结果:

[{ 'programming': 7 },
{ 'programming': 9 },
{ 'programming': 6 },
{ 'programming': 10 },
{ 'music': 1 },
{ 'music': 2 },
{ 'music': 3 },
{ 'music': 4 }]

我想通过键对它们进行分组并对值求和,得到:

[{'programming': 32},
 {'music': 10}]

按值排序(在本例中为第一次编程,然后是音乐)并限制为3(如果有programming 32music 10shopping 3lifestyle 1 ,只返回programmingshoppinglifestyle

如何汇总此类数据?我应该使用mapreduce,聚合还是简单分组?如果是这样,如何通过字典键告诉组到组?

谢谢

3 个答案:

答案 0 :(得分:1)

通过密钥执行此操作会破坏您的查询可维护性。

我最好的建议是:创建另一个密钥,比如说skill(这将是文档分组键)和一个名为value的密钥。
然后你会得到一个像这样的查询:

db.skills.aggregate([{
  $group: {
    _id: "$skill",
    value: { $sum: "$value" }
  }
}])

答案 1 :(得分:1)

虽然我建议使用@ gustavohenke的路线而没有按键分组,你可以使用mapreduce来做(我想不出用聚合做的方法,这会更多直线路线)

> var mapFunction = function() {
     for(var key in this) { 
        if(key!='_id') emit(key, this[key]); 
     } 
  };

> var reduceFunction = function(key, values) { return Array.sum(values); }

> db.data.mapReduce(mapFunction, reduceFunction, { out: 'bop' })
{
    "result" : "bop",
    "timeMillis" : 47,
    "counts" : {
        "input" : 8,
        "emit" : 8,
        "reduce" : 2,
        "output" : 2
    },
    "ok" : 1,
}
> db.bop.find().sort({value: -1}).limit(3)
{ "_id" : "programming", "value" : 32 }
{ "_id" : "music", "value" : 10 }
> 

答案 2 :(得分:1)

希望这会有所帮助。

经过测试:v3.6.5

db.cname.aggregate([
{
    $project:
    {
        _id: 0
    }
},
{
    $project:
    {
        "o":
        {
            $objectToArray: "$$ROOT"
        }
    }
},
{
    $unwind: "$o"
},
{
    $group:
    {
        _id: "$o.k",
        value:
        {
            $sum: "$o.v"
        }
    }
}])

输出

{ "_id" : "music", "value" : 10 }

{ "_id" : "programming", "value" : 32 }