Comment obtenir la taille d'un document unique dans Mongodb?

87

J'ai rencontré un comportement étrange de mongo et je voudrais le clarifier un peu ...
Ma demande est aussi simple que ça: je voudrais avoir une taille de document unique en collection. J'ai trouvé deux solutions possibles:

  • Object.bsonsize - une méthode javascript qui devrait renvoyer une taille en octets
  • db.collection.stats () - où il y a une ligne 'avgObjSize' qui produit une vue de taille "agrégée" (moyenne) sur les données. Il représente simplement la taille moyenne d'un seul document.

  • Lorsque je crée une collection de test avec un seul document, les deux fonctions renvoient des valeurs différentes. Comment est-ce possible?
    Existe-t-il une autre méthode pour obtenir la taille d'un document mongo?

Ici, je fournis du code sur lequel j'effectue des tests:

  1. J'ai créé une nouvelle base de données 'test' et entré un document simple avec un seul attribut: type: "auto"

    db.test.insert({type:"auto"})
    
  2. sortie de l'appel de fonction 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. sortie de l'appel de fonction bsonsize: Object.bsonsize (db.test.find ({test: "auto"}))

    481
    
user1949763
la source

Réponses:

179

Lors de l'appel précédent de Object.bsonsize(), Mongodb a renvoyé la taille du curseur plutôt que celle du document.

La bonne façon est d'utiliser cette commande:

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

Avec findOne(), vous pouvez définir votre requête pour un document spécifique:

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

Cela renverra la taille correcte (en octets) du document particulier.

user1949763
la source
1
Comment obtenir la taille d'une liste de documents avec requête?
leon
Mais bien sûr, ce code récupérera le document avant de calculer la taille.
Sercan Ozdemir
Cela ne retourne pas une bonne taille: (... Mais ceci: stackoverflow.com/a/40993183/3933634
Liberateur
3
Comment obtenir Object.bsonsize, quelle est la déclaration d'importation ou requise?
PARAMANANDA PRADHAN
7
Pour tous ceux qui l'ont manqué, vous devez utiliser à la findOneplace defind
Sam
36

J'ai recommandé d'utiliser ce script pour obtenir la taille réelle.

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

Remarque: Si vos ID sont des entiers 64 bits, ce qui précède tronquera la valeur de l'ID lors de l'impression! Si tel est le cas, vous pouvez utiliser à la place:

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

Cela a également l'avantage de renvoyer JSON, donc une interface graphique comme RoboMongo peut le tabuler!

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

edit: merci à @zAlbee pour votre suggestion.

Libérateur
la source
C'est exactement ce que je recherche mais cela ne fonctionne peut-être pas avec ma version mongo. celui actuel est de 3,4?
Erce
Quelqu'un d'autre obtient-il TypeError: Object.bsonsize is not a function?
Félix Paradis
Avez-vous essayé mongo shell? C'est du travail: docs.mongodb.com/manual/reference/mongo-shell/#miscellaneous
Liberateur
Une bonne étiquette serait plutôt '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

La quantité effective d'espace que le document prendra dans la collection sera supérieure à la taille de votre document en raison du mécanisme de remplissage d'enregistrement .

C'est pourquoi il existe une différence entre les sorties de db.test.stats()et Object.bsonsize(..).

Pour obtenir la taille exacte (en octets) du document, respectez la Object.bsonsize()fonction.

Konstantin Yovkov
la source
Merci pour votre réponse, dans ce cas, j'ai une autre question concernant ce problème: supposons que j'ai une collection où des documents avec une longue liste d'identifiants sont enregistrés sous la forme de la liste. (les identifiants sont stockés à l'origine dans un fichier txt-csv - d'une taille de 300 ko; chaque identifiant fait 10 caractères) Quand je lance bsonsize sur un tel document, la taille est encore inférieure à 481. Il renvoie 465. Pourriez-vous m'expliquer cette situation, S'il vous plaît?
user1949763
4
Quelle taille est utilisée pour appliquer la limitation de taille de document mongDB? Object.bsonsize ()?
John Evans
La taille du document MongoDB est une contrainte du Mongo, ceci est couvert dans le manuel sur leur site Web, 16 Mo. J'ai atteint cette limite plusieurs fois en essayant d'importer des enregistrements.
htm11h
3

Avec mongodb 4.4 (à venir), vous pouvez utiliser l' bsonSizeopérateur pour obtenir la taille du document.

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

Object.bsonsize (db.test.findOne ({type: "auto"})) Il donne en octets.

Visakh Vijayan
la source
3
Essayez d'expliquer votre réponse. .
Emmanuel Mtali