MongoDB Count() 与聚合

标签 mongodb mongodb-query nosql-aggregation

我在 mongo 中经常使用聚合,我知道分组计数等方面的性能优势。但是,mongo 在计算集合中所有文档的这两种方式的性能上有什么不同吗?:

collection.aggregate([
  {
    $match: {}
  },{
    $group: {
      _id: null, 
      count: {$sum: 1}
    }
}]);

collection.find({}).count()

更新:第二种情况: 假设我们有这个示例数据:

{_id: 1, type: 'one', value: true}
{_id: 2, type: 'two', value: false}
{_id: 4, type: 'five', value: false}

使用 aggregate():

var _ids = ['id1', 'id2', 'id3'];
var counted = Collections.mail.aggregate([
  {
    '$match': {
      _id: {
        '$in': _ids
      },
      value: false
    }
  }, {
    '$group': {
      _id: "$type",
      count: {
        '$sum': 1
      }
    }
  }
]);

使用count():

var counted = {};
var type = 'two';
for (i = 0, len = _ids.length; i < len; i++) {
  counted[_ids[i]] = Collections.mail.find({
    _id: _ids[i], value: false, type: type
  }).count();
}

最佳答案

.count() 要快得多。您可以通过调用查看实现

// Note the missing parentheses at the end
db.collection.count

返回游标的长度。默认查询(如果 count() 在没有查询文档的情况下被调用),它又被实现为返回 _id_ 索引的长度,iirc。

然而,聚合会读取每个文档并对其进行处理。这只能是与 .count() 相同数量级的一半,当只处理大约 100k 的文档时(根据您的 RAM 给予和接受)。

以下函数应用于包含大约 1200 万个条目的集合:

function checkSpeed(col,iterations){

  // Get the collection
  var collectionUnderTest = db[col];

  // The collection we are writing our stats to
  var stats = db[col+'STATS']

  // remove old stats
  stats.remove({})

  // Prevent allocation in loop
  var start = new Date().getTime()
  var duration = new Date().getTime()

  print("Counting with count()")
  for (var i = 1; i <= iterations; i++){
    start = new Date().getTime();
    var result = collectionUnderTest.count()
    duration = new Date().getTime() - start
    stats.insert({"type":"count","pass":i,"duration":duration,"count":result})
  }

  print("Counting with aggregation")
  for(var j = 1; j <= iterations; j++){
    start = new Date().getTime()
    var doc = collectionUnderTest.aggregate([{ $group:{_id: null, count:{ $sum: 1 } } }])
    duration = new Date().getTime() - start
    stats.insert({"type":"aggregation", "pass":j, "duration": duration,"count":doc.count})
  }

  var averages = stats.aggregate([
   {$group:{_id:"$type","average":{"$avg":"$duration"}}} 
  ])

  return averages
}

并返回:

{ "_id" : "aggregation", "average" : 43828.8 }
{ "_id" : "count", "average" : 0.6 }

单位是毫秒。

第一个

关于MongoDB Count() 与聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33181878/

相关文章:

node.js - 我如何使用 Node.js 和 Mongoose 计算总正价、总负价和总和

mongodb 乘法聚合运算符

node.js - MongoDB 性能问题,可能是由于使用 native MongoDB 驱动程序在 NodeJS 项目中忽略了投影

spring - 在 MongoDB for Spring 中查找/删除 @DBref 列表项

arangodb - 如何对 ArangoDB 中的文档字段执行原子操作?

scala - 如何使用 Scala 计算 Hbase 表上的所有行

javascript - 使用 MongoDB $setEquals 时引号中的 ID

c# - 当主服务器出现故障时,有没有办法自动使 MongoDB C# 驱动程序不抛出 EndOfStreamException ?

java - Java中使用Mockito模拟MongoDB的DeleteResult