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

Posted

技术标签:

【中文标题】Mongodb如何获取单个文档的大小?【英文标题】:How to get the size of single document in Mongodb? 【发布时间】:2014-03-27 08:36:40 【问题描述】:

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

Object.bsonsize - 一些应该返回字节大小的 javascript 方法 db.collection.stats() - 有一行“avgObjSize”在数据上产生一些“聚合”(平均)大小视图。它只是表示单个文档的平均大小。 当我只用一个文档创建测试集合时,两个函数都返回不同的值。这怎么可能? 是否存在其他方法来获取 mongo 文档的大小?

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

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

    db.test.insert(type:"auto")
    

    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
    

    bsonsize 函数调用的输出:Object.bsonsize(db.test.find(test:"auto"))

    481
    

【问题讨论】:

【参考方案1】:

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

正确的方法是使用这个命令:

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

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

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

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

【讨论】:

如何通过查询获取文档列表的大小? 当然,这段代码会在计算大小之前获取文档。 如何获取Object.bsonsize,import或required语句是什么? 对于其他错过它的人,您必须使用findOne 而不是find 在python中怎么做?【参考方案2】:

最大文档大小 16 MiB (source)


如果您的版本 >=4.4 ($bsonSizesource)

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

如果您的版本 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 的建议完成。

【讨论】:

这正是我正在寻找的,但它不起作用可能与我的 mongo 版本有关。当前是3.4? 还有其他人得到TypeError: Object.bsonsize is not a function 吗? 你在 mongo shell 中尝试过吗?它的工作:docs.mongodb.com/manual/reference/mongo-shell/#miscellaneous 正确的标签应该是'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024))(或'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))【参考方案3】:

由于Record Padding 机制,文档在集合中占用的有效空间量将超过文档的大小。

这就是db.test.stats()Object.bsonsize(..) 的输出之间存在差异的原因。

要获得文档的准确大小(以字节为单位),请使用Object.bsonsize() 函数。

【讨论】:

感谢您的回复,在这种情况下,我对这个问题还有另一个问题:假设我有一个集合,其中具有长标识符列表的文档以列表的形式保存。 (标识符最初存储在 txt-csv 文件中,大小为 300 kB;每个标识符的长度为 10 个字符)当我在这样的文档上运行 bsonsize 时,大小甚至低于 481。它返回 465。可以请您向我解释一下这种情况? 哪个大小用于强制执行 mongDB 文档大小限制? Object.bsonsize()? MongoDB 文档大小是 Mongo 的一个约束,这在他们网站上的手册中有介绍,16MB。尝试导入记录时,我已多次达到此限制。【参考方案4】:

使用mongodb 4.4(即将推出),可以使用bsonSize操作符获取文档大小。

db.test.aggregate([
  
    "$project": 
      "name": 1,
      "object_size":  "$bsonSize": "$$ROOT" 
    
  
])

【讨论】:

【参考方案5】:

Object.bsonsize(db.test.findOne(type:"auto")) 它以字节为单位。

【讨论】:

试着解释你的答案。 .【参考方案6】:

方法Object.bsonsize() 仅在旧版mongo shell 中可用。在新的mongosh 中,您必须使用包bson

const BSON = require("bson");

BSON.calculateObjectSize(field: "value")

BSON.calculateObjectSize(db.test.findOne())

【讨论】:

以上是关于Mongodb如何获取单个文档的大小?的主要内容,如果未能解决你的问题,请参考以下文章

您如何从 mongodb 获取单个项目并显示它? (默恩)

如何在mongodb查询中获取单个字段?

带有 mgo 的 Go (golang) 中的 MongoDB:如何更新记录、确定更新是不是成功并在单个原子操作中获取数据?

如何在 mongoDB 中获取最后 50 个文档? [复制]

MongoDB:如何获取包含最接近给定数字的数值的文档

MongoDB:如何使用 _id 获取集合中的最新文档?