Wie erhalte ich die Größe eines einzelnen Dokuments in Mongodb?

83

Ich bin auf ein seltsames Verhalten von Mongo gestoßen und möchte es ein wenig klären ...
Meine Anfrage ist so einfach: Ich möchte eine Größe eines einzelnen Dokuments in der Sammlung haben. Ich habe zwei mögliche Lösungen gefunden:

  • Object.bsonsize - eine Javascript-Methode, die eine Größe in Bytes zurückgeben sollte
  • db.collection.stats () - Hier gibt es eine Zeile 'avgObjSize', die eine "aggregierte" (durchschnittliche) Größenansicht der Daten erzeugt. Es repräsentiert einfach die durchschnittliche Größe eines einzelnen Dokuments.

  • Wenn ich eine Testsammlung mit nur einem Dokument erstelle, geben beide Funktionen unterschiedliche Werte zurück. Wie ist es möglich?
    Gibt es eine andere Methode, um die Größe eines Mongo-Dokuments zu ermitteln?

Hier stelle ich einen Code bereit, an dem ich Tests durchführe:

  1. Ich habe eine neue Datenbank 'test' erstellt und ein einfaches Dokument mit nur einem Attribut eingegeben: type: "auto"

    db.test.insert({type:"auto"})
  2. Ausgabe des Funktionsaufrufs 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. Ausgabe des Funktionsaufrufs bsonsize: Object.bsonsize (db.test.find ({test: "auto"}))

    481
user1949763
quelle

Antworten:

175

Beim vorherigen Aufruf von Object.bsonsize()gab Mongodb die Größe des Cursors anstelle des Dokuments zurück.

Der richtige Weg ist, diesen Befehl zu verwenden:

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

Mit findOne()können Sie Ihre Abfrage für ein bestimmtes Dokument definieren:

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

Dadurch wird die korrekte Größe (in Byte) des jeweiligen Dokuments zurückgegeben.

user1949763
quelle
1
Wie erhalte ich die Größe einer Liste von Dokumenten mit Abfrage?
Leon
Aber natürlich ruft dieser Code das Dokument ab, bevor die Größe berechnet wird.
Sercan Ozdemir
Dies gibt keine gute Größe zurück: (... Aber dies: stackoverflow.com/a/40993183/3933634
Liberateur
3
Wie bekomme ich Object.bsonsize, was ist der Import oder die erforderliche Anweisung?
PARAMANANDA PRADHAN
7
Für alle anderen, die es verpasst haben, müssen Sie findOneanstelle vonfind
Sam
31

Der effektive Speicherplatz, den das Dokument in der Sammlung einnimmt, ist aufgrund des Mechanismus zum Auffüllen von Datensätzen größer als die Größe Ihres Dokuments .

Aus diesem Grund gibt es einen Unterschied zwischen den Ausgängen von db.test.stats()und Object.bsonsize(..).

Um die genaue Größe (in Byte) des Dokuments zu erhalten, halten Sie sich an die Object.bsonsize()Funktion.

Konstantin Yovkov
quelle
Vielen Dank für Ihre Antwort. In diesem Fall habe ich eine weitere Frage zu diesem Problem: Angenommen, ich habe eine Sammlung, in der Dokumente mit einer langen Liste von Kennungen in Form der Liste gespeichert werden. (Bezeichner werden ursprünglich in einer txt-csv-Datei mit einer Größe von 300 kB gespeichert; jeder Bezeichner ist 10 Zeichen lang.) Wenn ich bsonsize für ein solches Dokument ausführe, ist die Größe sogar kleiner als 481. Sie gibt 465 zurück. Können Sie mir diese Situation erklären ? Bitte?
user1949763
4
Welche Größe wird verwendet, um die Beschränkung der mongDB-Dokumentgröße durchzusetzen? Object.bsonsize ()?
John Evans
Die MongoDB-Dokumentgröße ist eine Einschränkung des Mongo. Dies wird im Handbuch auf seiner Website (16 MB) behandelt. Ich habe dieses Limit mehrmals beim Importieren von Datensätzen erreicht.
htm11h
31

Ich habe empfohlen, dieses Skript zu verwenden, um die tatsächliche Größe zu erhalten.

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

Hinweis: Wenn Ihre IDs 64-Bit-Ganzzahlen sind, wird der ID-Wert beim Drucken durch die obigen Angaben abgeschnitten! Wenn dies der Fall ist, können Sie stattdessen Folgendes verwenden:

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

Dies hat auch den Vorteil, dass JSON zurückgegeben wird, sodass eine GUI wie RoboMongo es tabellieren kann!

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

edit: danke an @zAlbee für deinen Vorschlag zur Fertigstellung.

Liberateur
quelle
Dies ist genau das, wonach ich suche, aber es funktioniert nicht, möglicherweise im Zusammenhang mit meiner Mongo-Version. aktuelle ist 3,4?
Erce
Bekommt sonst noch jemand TypeError: Object.bsonsize is not a function?
Félix Paradis
Haben Sie in Mongo Shell versucht? Es ist Arbeit: docs.mongodb.com/manual/reference/mongo-shell/#miscellaneous
Liberateur
Richtiges Label wäre eher 'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024))(oder'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))
Wernfried Domscheit
0

Object.bsonsize (db.test.findOne ({type: "auto"})) Gibt in Bytes an.

Visakh Vijayan
quelle
2
Versuchen Sie, Ihre Antwort zu erklären. .
Emmanuel Mtali
0

Mit mongodb 4.4 (in Vorbereitung ) können Sie den bsonSizeOperator verwenden, um die Dokumentgröße abzurufen .

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