如何在MongoDB集合中的所有文档中对键的值求和

JAM*_*JAM 41 mongodb nosql

我在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 }
Run Code Online (Sandbox Code Playgroud)

如何"subida"在所有文档中总结密钥的值?有了上面的文件,我应该收到以下内容:

{ "subida" : 17.47 }
Run Code Online (Sandbox Code Playgroud)

Ily*_*luk 120

在这种情况下,聚合比mapReduce更简单,更有效:

db.collection.aggregate({
    $group: {
        _id: '',
        subida: { $sum: '$subida' }
    }
 }, {
    $project: {
        _id: 0,
        subida: '$subida'
    }
})
Run Code Online (Sandbox Code Playgroud)
  1. 使用$ group with $ sum来计算总和
  2. 使用projection的$ project运算符删除$ group运算符所需的id键

  • MapReduce引擎是一个单线程的javascript.它也没有使用任何索引.聚合框架是多线程的本机c ++,并尽可能使用索引. (3认同)
  • 这种方法比Map/Reduce的当前实现更有效 (2认同)

小智 16

我个人会在集合上执行mapreduce:

map是一个发出"subida"字段的简单函数.如果你需要一笔钱,关键应该是一样的; reduce之后的结果将产生单个对象{<key>: <sum>},其中包含<key>您在emit中提供的任何值.

map = function() { emit(<key>, this.subida); }
Run Code Online (Sandbox Code Playgroud)

reduce也是一个简单的函数,将它们相加:

red = function(k, v) {
  var i, sum = 0;
  for (i in v) {
    sum += v[i];
  }
  return sum;
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在您的集合上调用mapreduce <mycollection>:

res = db.<mycollection>.mapReduce(map, red);
Run Code Online (Sandbox Code Playgroud)

这将创建一个临时的新集合,您可以像任何其他集合一样操作.mapReduce返回的值包含有关mapReduce的几个值,例如所用的时间,状态...以及temp.在"结果"字段中创建的集合名称.要获取所需的值,您必须查询该集合:

db[res.result].find()
Run Code Online (Sandbox Code Playgroud)

哪个应该给你这个对象{<key>: <sum>}.

如果你运行MongoDB 1.7.4或更高版本,你可以通过让MongoDB直接返回结果而不创建集合来节省一些麻烦:

db.<mycollection>.mapReduce(map, red, {out : {inline: 1}});
Run Code Online (Sandbox Code Playgroud)


Ian*_*cer 6

选项0:使用MongoDB聚合管道
[注意:在提出此问题后很长一段时间内添加了此选项,但现在是正确的方法]


选项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认同)

Sat*_*hia 6

使用这个最简单的查询来获取结果的总和

db.collection.aggregate({
    $group: {
        _id: '',
        subida: { $sum: '$subida' }
    }
 }
)
Run Code Online (Sandbox Code Playgroud)