Como obter o tamanho de um único documento no Mongodb?


87

Encontrei um comportamento estranho de mongo e gostaria de esclarecê-lo um pouco ...
Meu pedido é simples assim: gostaria de obter um tamanho de documento único na coleção. Encontrei duas soluções possíveis:

  • Object.bsonsize - algum método javascript que deve retornar um tamanho em bytes
  • db.collection.stats () - onde há uma linha 'avgObjSize' que produz uma visão do tamanho "agregado" (médio) nos dados. Ele simplesmente representa o tamanho médio de um único documento.

  • Quando eu crio uma coleção de teste com apenas um documento, ambas as funções retornam valores diferentes. Como isso é possível?
    Existe algum outro método para obter o tamanho de um documento mongo?

Aqui, eu forneço alguns códigos em que realizo testes:

  1. Criei um novo banco de dados 'teste' e entrada documento simples com apenas um atributo: tipo: "auto"

    db.test.insert({type:"auto"})
    
  2. saída da chamada de função 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. saída da chamada de função bsonsize: Object.bsonsize (db.test.find ({test: "auto"}))

    481
    

Respostas:


179

Na chamada anterior de Object.bsonsize(), Mongodb retornou o tamanho do cursor, em vez do documento.

A maneira correta é usar este comando:

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

Com findOne(), você pode definir sua consulta para um documento específico:

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

Isso retornará o tamanho correto (em bytes) do documento específico.


1
Como obter o tamanho de uma lista de documentos com consulta?
leon

Mas é claro que este código irá buscar o documento antes de calcular o tamanho.
Sercan Ozdemir

Isso não retornou um bom tamanho: (... Mas isso: stackoverflow.com/a/40993183/3933634
Liberateur

3
Como obter Object.bsonsize, qual é a importação ou declaração necessária?
PARAMANANDA PRADHAN

7
Para quem mais perdeu, você deve usar em findOnevez defind
Sam

36

Recomendei usar este script para obter o tamanho real.

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

Nota: Se seus IDs forem inteiros de 64 bits, o código acima irá truncar o valor do ID na impressão! Se for esse o caso, você pode usar em seu lugar:

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

Isso também tem a vantagem de retornar JSON, para que uma GUI como o RoboMongo possa tabulá-lo!

fonte: https://stackoverflow.com/a/16957505/3933634

editar: obrigado a @zAlbee por sua sugestão de conclusão.


Isso é exatamente o que estou procurando, mas não está funcionando, talvez relacionado com a minha versão do mongo. o atual é de 3,4?
Erce

Alguém mais está recebendo TypeError: Object.bsonsize is not a function?
Félix Paradis

Você tem que tentar no shell mongo? É trabalho: docs.mongodb.com/manual/reference/mongo-shell/#misc Miscellaneous
Liberateur

O rótulo adequado seria 'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024))(ou'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))
Wernfried Domscheit

31

A quantidade efetiva de espaço que o documento ocupará na coleção será maior do que o tamanho do seu documento devido ao mecanismo de preenchimento de registro .

É por isso que há uma diferença entre as saídas de db.test.stats()e Object.bsonsize(..).

Para obter o tamanho exato (em bytes) do documento, siga a Object.bsonsize()função.


Obrigado pela sua resposta, nesse caso, tenho outra pergunta a respeito deste assunto: suponha que eu tenha uma coleção onde documentos com uma longa lista de identificadores são salvos na forma de lista. (os identificadores são armazenados originalmente no arquivo txt-csv - com tamanho de 300 kB; cada identificador tem 10 caracteres) Quando eu executo bsonsize em um documento assim, o tamanho é ainda menor que 481. Ele retorna 465. Você poderia me explicar esta situação, por favor?
user1949763

4
Qual tamanho é usado para impor a limitação de tamanho do documento mongDB? Object.bsonsize ()?
John Evans,

O tamanho do documento MongoDB é uma restrição do Mongo, isso é abordado no manual em seu site, 16 MB. Atingi esse limite várias vezes ao tentar importar registros.
htm11h

3

Com mongodb 4.4 (a ser lançado), você pode usar o bsonSizeoperador para obter o tamanho do documento.

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.