我有以下记录集作为查找结果:
[{ 'programming': 7 },
{ 'programming': 9 },
{ 'programming': 6 },
{ 'programming': 10 },
{ 'music': 1 },
{ 'music': 2 },
{ 'music': 3 },
{ 'music': 4 }]
我想通过键对它们进行分组并对值求和,得到:
[{'programming': 32},
{'music': 10}]
按值排序(在本例中为第一次编程,然后是音乐)并限制为3(如果有programming 32
,music 10
,shopping 3
和lifestyle 1
,只返回programming
,shopping
和lifestyle
。
如何汇总此类数据?我应该使用mapreduce,聚合还是简单分组?如果是这样,如何通过字典键告诉组到组?
谢谢
答案 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 }