106

I encountered a strange behavior of mongo and I would like to clarify it a bit...
My request is simple as that: I would like to get a size of single document in collection. I found two possible solutions:

  • Object.bsonsize - some javascript method that should return a size in bytes
  • db.collection.stats() - where there is a line 'avgObjSize' that produce some "aggregated"(average) size view on the data. It simply represents average size of single document.

  • When I create test collection with only one document, both functions returns different values. How is it possible?
    Does it exist some other method to get a size of a mongo document?

Here, I provide some code I perform testing on:

  1. I created new database 'test' and input simple document with only one attribute: type:"auto"

    db.test.insert({type:"auto"})
    
  2. output from stats() function call: 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. output from bsonsize function call: Object.bsonsize(db.test.find({test:"auto"}))

    481
    
4

6 回答 6

208

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

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

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

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

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

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

于 2014-03-04T08:22:33.810 回答
46

最大文档大小 16 MiB(来源


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

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的建议完成。

于 2016-12-06T10:33:10.167 回答
34

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

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

要获得文档的确切大小(以字节为单位),请坚持使用该Object.bsonsize()功能。

于 2014-02-25T09:03:17.577 回答
11

使用 mongodb 4.4(即将推出),您可以使用bsonSize运算符来获取文档大小。

db.test.aggregate([
  {
    "$project": {
      "name": 1,
      "object_size": { "$bsonSize": "$$ROOT" }
    }
  }
])
于 2020-04-27T05:17:35.003 回答
3

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

于 2020-03-11T12:31:41.550 回答
0

方法Object.bsonsize()仅在旧版mongoshell 中可用。在新的mongosh你必须使用包bson

const BSON = require("bson");

BSON.calculateObjectSize({field: "value"})

BSON.calculateObjectSize(db.test.findOne())
于 2022-01-13T13:55:32.443 回答