How to get the size of single document in Mongodb?
Asked Answered
H

6

128

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
    
Hornbeck answered 25/2, 2014 at 8:45 Comment(0)
H
226

In the previous call of Object.bsonsize(), Mongodb returned the size of the cursor, rather than the document.

Correct way is to use this command:

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

With findOne(), you can define your query for a specific document:

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

This will return the correct size (in bytes) of the particular document.

Hornbeck answered 4/3, 2014 at 8:22 Comment(7)
How to get the size of a list of document with query?My
But of course this code will fetch the document before calculating the size.Sethrida
This not return a goood size :(... But this : https://mcmap.net/q/173862/-how-to-get-the-size-of-single-document-in-mongodbGorgonzola
How to get Object.bsonsize, what is the import or required statement?Basir
For anyone else who missed it, you must use findOne instead of findNeiman
how to do it in python?Kenrick
For anyone else who missed it, you must use findOne or find().toArray() instead of find Using find().toArray() of course gives the size sum of all documents.Machination
G
71

MAXIMUM DOCUMENT SIZE 16 MiB (source)


If you have version >=4.4 ($bsonSize source)

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

If you have version <4.4 (Object.bsonSize() source)

You can use this script for get a real size:

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)');
});

Note: If your IDs are 64-bit integers, the above will truncate the ID value on printing! If that's the case, you can use instead:

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(tojson(stats));
});

This also has the advantage of returning JSON, so a GUI like RoboMongo can tabulate it!


edit : thanks to @zAlbee for your suggest completion.

Gorgonzola answered 6/12, 2016 at 10:33 Comment(5)
This is exactly what i am looking for but it not working maybe related with my mongo version. current one is 3.4 ?Alar
Anyone else getting TypeError: Object.bsonsize is not a function ?Benzophenone
Do you have try in mongo shell ? It's work : docs.mongodb.com/manual/reference/mongo-shell/#miscellaneousGorgonzola
Proper label would be rather 'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024)) (or 'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))Machination
print(tojson(stats)); edit queue is full -.-Deadwood
S
37

The effective amount of space the document will take in the collection will be more than the size of your document because of the Record Padding mechanism.

This is why there is a difference between the outputs of the db.test.stats() and Object.bsonsize(..).

To get the exact size (in bytes) of the document, stick to the Object.bsonsize() function.

Slide answered 25/2, 2014 at 9:3 Comment(3)
Thank you for your reply, in that case, I have another question regarding this issue: suppose I have a collection where documents with long list of identifiers are saved in the form of the list. (identifiers are stored originally in txt-csv file- with size 300 kB; each identifier is 10characters long) When I run bsonsize on such a document the size is even lower than 481. It returns 465. Could you explain to me this situation, please?Hornbeck
Which size is used to enforce the mongDB document size limitation? Object.bsonsize()?Nodal
The MongoDB document size is a constraint of the Mongo, this is covered in the manual on their web site, 16MB. I have hit this limit a number of times trying import records.Beeeater
W
16

With mongodb 4.4 (upcoming), You can use bsonSize operator to get the document size.

db.test.aggregate([
  {
    "$project": {
      "name": 1,
      "object_size": { "$bsonSize": "$$ROOT" }
    }
  }
])
Waste answered 27/4, 2020 at 5:17 Comment(0)
M
4

Method Object.bsonsize() is available only in legacy mongo shell. In new mongosh you have to use package bson or mongocompat snippets

const BSON = require("bson");

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

BSON.calculateObjectSize(db.test.findOne())
Machination answered 13/1, 2022 at 13:55 Comment(0)
F
3

Object.bsonsize(db.test.findOne({type:"auto"})) It gives in bytes.

Fessler answered 11/3, 2020 at 12:31 Comment(1)
Try to explain your answer . .Fidelis

© 2022 - 2024 — McMap. All rights reserved.