如何对 MongoDB 集合中所有文档的键值求和
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4621300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to sum the value of a key across all documents in a MongoDB collection
提问by JAM
I have collection in MongoDB:
我在 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 }
How I can sum the value of a key, e.g., "subida"
, across all documents? With the documents above, I should receive something along the lines of:
我如何总结"subida"
所有文档中的键值,例如,?有了上面的文件,我应该会收到以下内容:
{ "subida" : 17.47 }
采纳答案by Yochiro
I'd personally perform a mapreduce on the collection :
我会亲自对集合执行 mapreduce :
map is a simple function emitting the "subida" field. The key should the same if you need a single sum; the result after reduce will yield the single object {<key>: <sum>}
, with <key>
being whatever value you supplied in the emit.
map 是一个发出“subida”字段的简单函数。如果您需要一个总和,密钥应该相同;reduce 之后的结果将产生单个 object {<key>: <sum>}
,它<key>
是您在发射中提供的任何值。
map = function() { emit(<key>, this.subida); }
reduce is also a simple function summing them :
reduce 也是一个简单的函数:
red = function(k, v) {
var i, sum = 0;
for (i in v) {
sum += v[i];
}
return sum;
}
You can then call mapreduce on your collection <mycollection>
:
然后你可以在你的集合上调用 mapreduce <mycollection>
:
res = db.<mycollection>.mapReduce(map, red);
Which will create a temporary new collection you can manipulate like any other collection. The value returned by mapReduce holds several values regarding the mapReduce such as the time taken, status..., as well as the temp. collection name created in the "result" field. To get the values you need, you have to query that collection :
这将创建一个临时的新集合,您可以像任何其他集合一样操作。mapReduce 返回的值包含有关 mapReduce 的几个值,例如所用时间、状态...以及临时值。在“结果”字段中创建的集合名称。要获得您需要的值,您必须查询该集合:
db[res.result].find()
Which should give you the object {<key>: <sum>}
.
这应该给你对象{<key>: <sum>}
。
If you run MongoDB 1.7.4 or higher, you can save you a bit of hassle by asking MongoDB to return the result directly without creating a collection :
如果您运行 MongoDB 1.7.4 或更高版本,您可以通过要求 MongoDB 直接返回结果而不创建集合来节省一些麻烦:
db.<mycollection>.mapReduce(map, red, {out : {inline: 1}});
回答by Ilya Builuk
In this case, aggregation is much simpler and much more efficient than mapReduce:
在这种情况下,聚合比 mapReduce 简单得多,效率也高得多:
db.collection.aggregate({
$group: {
_id: '',
subida: { $sum: '$subida' }
}
}, {
$project: {
_id: 0,
subida: '$subida'
}
})
- use $group with $sum to calculate sum
- use projection's $project operator to remove id key required by $group operator
- 使用 $group 和 $sum 来计算总和
- 使用投影的 $project 运算符删除 $group 运算符所需的 id 键
回答by Ian Mercer
Option 0: Use the MongoDB aggregation pipeline
[NB: this option was added a long time after this question was asked but is the right approach now]
选项 0:使用MongoDB 聚合管道
[注意:此选项是在提出此问题后很长时间才添加的,但现在是正确的方法]
Option 1: Query all the records, return only the subida field from Mongo and add them up by iterating over the Mongo cursor client side.
选项 1:查询所有记录,仅从 Mongo 返回 subida 字段,并通过遍历 Mongo 游标客户端将它们相加。
Option 2: Write a map reduce command that emits only the subdia field (same key for all) and then a reduce command that totals them.
选项 2:编写一个仅发出 subdia 字段(所有关键字相同)的 map reduce 命令,然后编写一个将它们总计的 reduce 命令。
Option 3: Use db.eval to execute javascript on the server: http://www.mongodb.org/display/DOCS/Server-side+Code+Execution
选项3:使用db.eval在服务器上执行javascript:http: //www.mongodb.org/display/DOCS/Server-side+Code+Execution
Option 4: Accumulate 'subida' values as you insert values into your collection so that you have an up-to-date total at hand whenever you need it. You can store the total in a different document and use atomic "update if current" operations to update it: http://www.mongodb.org/display/DOCS/Atomic+Operations
选项 4:在您将值插入到您的集合中时累积 'subida' 值,以便您在需要时随时掌握最新的总数。您可以将总数存储在不同的文档中,并使用原子“如果当前更新”操作来更新它:http: //www.mongodb.org/display/DOCS/Atomic+Operations
回答by Shakthifuture
Use this simplest query to get the sum of the result
使用这个最简单的查询来获取结果的总和
db.collection.aggregate({
$group: {
_id: '',
subida: { $sum: '$subida' }
}
}
)
回答by oscarcardoso
You are able to use the collection as an array, just add the values in a loop.
您可以将集合用作数组,只需在循环中添加值。
Edit: Yes, this is a bad practice when having a big dataset.
编辑:是的,当数据集很大时,这是一个不好的做法。