如何在Mongodb中获取单个文档的大小?

我遇到了一个奇怪的mongo行为,我想澄清一下......
我的请求很简单:我想在集合中获得单个文档的大小。我发现了两种可能的解决方案:

  • Object.bsonsize - 一些应该返回大小(以字节为单位)的javascript方法
  • db.collection.stats() - 其中有一行'avgObjSize'在数据上产生一些“聚合”(平均)大小视图。它只是表示单个文档的平均大小。

  • 当我仅使用一个文档创建测试集合时,两个函数返回不同的值。这怎么可能?
    是否存在其他一些方法来获取mongo文档的大小?

在这里,我提供了一些执行测试的代码:

  1. 我创建了新的数据库“test”并输入了只有一个属性的简单文档:type:“auto”

    db.test.insert({type:"auto"})
    
  2. 来自 stats() 函数调用的输出: db.test.stats()

    { 
      "ns" : "test.test",
      "count" : 1,
      "size" : 40,
      "avgObjSize" : 40,
      "storageSize" : 4096,
      "numExtents" : 1,
      "nindexes" : 1,
      "lastExtentSize" : 4096,
      "paddingFactor" : 1,
      "systemFlags" : 1,
      "userFlags" : 0,
      "totalIndexSize" : 8176,
      "indexSizes" : {
            "_id_" : 8176
    },
    "ok" : 1
    

    }

  3. bsonsize 函数调用的输出: Object.bsonsize(db.test.find({test:“auto”}))

    481
    

答案 1

在前面的调用中,Mongodb 返回了游标的大小,而不是文档的大小。Object.bsonsize()

正确的方法是使用以下命令:

Object.bsonsize(db.test.findOne())

使用 ,您可以定义特定文档的查询:findOne()

Object.bsonsize(db.test.findOne({type:"auto"}))

这将返回特定文档的正确大小(以字节为单位)。


答案 2

最大文档大小 16 MiB(


如果您的版本 >=4.4($bsonSize源代码

db.users.aggregate([
  {
    "$project": {
      "size_bytes": { "$bsonSize": "$$ROOT" },
      "size_KB": { "$divide": [{"$bsonSize": "$$ROOT"}, 1000] },
      "size_MB": { "$divide": [{"$bsonSize": "$$ROOT"}, 1000000] }
    }
  }
])

如果您使用的是版本 <4.4(Object.bsonSize() source

您可以使用此脚本获取实际大小:

db.users.find().forEach(function(obj)
{
  var size = Object.bsonsize(obj);
  print('_id: '+obj._id+' || Size: '+size+'B -> '+Math.round(size/(1000))+'KB -> '+Math.round(size/(1000*1000))+'MB (max 16MB)');
});

注意:如果您的 ID 是 64 位整数,则上述内容将在打印时截断 ID 值!如果是这种情况,您可以改用:

db.users.find().forEach(function(obj)
{
  var size = Object.bsonsize(obj);
  var stats =
  {
    '_id': obj._id, 
    'bytes': size, 
    'KB': Math.round(size/(1000)), 
    'MB': Math.round(size/(1000*1000))
  };
  print(stats);
});

这也具有返回JSON的优点,因此像RoboMongo这样的GUI可以将其制成表格!


编辑 :感谢@zAlbee的建议完成。