我在MongoDB中有收集:
{ "_id" : ObjectId("4d2407265ff08824e3000001"), "subida" : 3.95 }
{ "_id" : ObjectId("4d2551b4ae9fa739640df821"), "subida" : 6.03 }
{ "_id" : ObjectId("4d255b115ff08821c2000001"), "subida" : 5.53 }
{ "_id" : ObjectId("4d25e8d55ff08814f8000001"), "subida" : 1.96 }
如何在所有文档中汇总密钥的值,例如"subida"
?根据上述文件,我应该收到以下内容:
{ "subida" : 17.47 }
答案 0 :(得分:114)
在这种情况下,聚合比mapReduce更简单,更有效:
db.collection.aggregate({
$group: {
_id: '',
subida: { $sum: '$subida' }
}
}, {
$project: {
_id: 0,
subida: '$subida'
}
})
答案 1 :(得分:16)
我个人在集合上执行mapreduce:
map是一个发出“subida”字段的简单函数。如果你需要一笔钱,关键应该是一样的; reduce之后的结果将产生单个对象{<key>: <sum>}
,其中<key>
是您在emit中提供的任何值。
map = function() { emit(<key>, this.subida); }
reduce也是一个简单的函数总结它们:
red = function(k, v) {
var i, sum = 0;
for (i in v) {
sum += v[i];
}
return sum;
}
然后,您可以在集合<mycollection>
上调用mapreduce:
res = db.<mycollection>.mapReduce(map, red);
这将创建一个临时的新集合,您可以像任何其他集合一样进行操作。 mapReduce返回的值包含有关mapReduce的几个值,例如所用的时间,状态...以及temp。在“结果”字段中创建的集合名称。 要获得所需的值,您必须查询该集合:
db[res.result].find()
哪个应该为您提供对象{<key>: <sum>}
。
如果您运行MongoDB 1.7.4或更高版本,可以让MongoDB直接返回结果而不创建集合,从而为您节省一些麻烦:
db.<mycollection>.mapReduce(map, red, {out : {inline: 1}});
答案 2 :(得分:6)
选项0:使用MongoDB aggregation pipeline
[注意:这个问题在被问到这个问题后很长一段时间被添加了,但现在是正确的方法]
选项1:查询所有记录,仅返回Mongo的subida字段,并通过遍历Mongo游标客户端添加它们。
选项2:编写一个map reduce命令,它只发出一个子字段(所有的相同键),然后是一个总计它们的reduce命令。
选项3:使用db.eval在服务器上执行javascript:http://www.mongodb.org/display/DOCS/Server-side+Code+Execution
选项4:在您向集合中插入值时累积“subida”值,以便在需要时随时获得最新总计。您可以将总数存储在不同的文档中,并使用原子“更新当前”操作来更新它:http://www.mongodb.org/display/DOCS/Atomic+Operations
答案 3 :(得分:0)
您可以将集合用作数组,只需在循环中添加值即可。
修改:是的,拥有大型数据集时,这是一种不好的做法。
答案 4 :(得分:0)
使用这个最简单的查询来获取结果的总和
db.collection.aggregate({
$group: {
_id: '',
subida: { $sum: '$subida' }
}
}
)