Jak uzyskać rozmiar pojedynczego dokumentu w Mongodb?

87

Napotkałem dziwne zachowanie mongo i chciałbym to nieco wyjaśnić ...
Moja prośba jest prosta: chciałbym uzyskać rozmiar pojedynczego dokumentu w kolekcji. Znalazłem dwa możliwe rozwiązania:

  • Object.bsonsize - jakaś metoda javascript, która powinna zwrócić rozmiar w bajtach
  • db.collection.stats () - gdzie znajduje się wiersz 'avgObjSize', który generuje pewien "zagregowany" (średni) widok rozmiaru danych. Po prostu reprezentuje średni rozmiar pojedynczego dokumentu.

  • Kiedy tworzę kolekcję testową z tylko jednym dokumentem, obie funkcje zwracają różne wartości. Jak to jest możliwe?
    Czy istnieje inna metoda uzyskania rozmiaru dokumentu mongo?

Tutaj podaję kod, na którym przeprowadzam testy:

  1. Utworzyłem nową bazę danych „test” i wprowadziłem prosty dokument z tylko jednym atrybutem: typ: „auto”

    db.test.insert({type:"auto"})
    
  2. dane wyjściowe z wywołania funkcji 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. dane wyjściowe wywołania funkcji bsonsize: Object.bsonsize (db.test.find ({test: "auto"}))

    481
    
user1949763
źródło

Odpowiedzi:

181

W poprzednim wywołaniu programu Object.bsonsize()Mongodb zwracał rozmiar kursora, a nie dokumentu.

Poprawnym sposobem jest użycie tego polecenia:

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

Za pomocą findOne()możesz zdefiniować zapytanie dla konkretnego dokumentu:

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

Zwróci to prawidłowy rozmiar (w bajtach) konkretnego dokumentu.

user1949763
źródło
1
Jak uzyskać rozmiar listy dokumentów z zapytaniem?
Leon
Ale oczywiście ten kod pobierze dokument przed obliczeniem rozmiaru.
Sercan Ozdemir
To nie zwraca dobrego rozmiaru: (... Ale to: stackoverflow.com/a/40993183/3933634
Liberateur
4
Jak zdobyć Object.bsonsize, jaki jest import lub wymagana instrukcja?
PARAMANANDA PRADHAN
8
Dla każdego, kto to przegapił, musisz użyć findOnezamiastfind
Sam
36

Poleciłem użyć tego skryptu, aby uzyskać rzeczywisty rozmiar.

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

Uwaga: jeśli Twoje identyfikatory są 64-bitowymi liczbami całkowitymi, powyższe spowoduje obcięcie wartości identyfikatora podczas drukowania! W takim przypadku możesz zamiast tego użyć:

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

Ma to również tę zaletę, że zwraca JSON, więc GUI, takie jak RoboMongo, może to zestawić!

źródło: https://stackoverflow.com/a/16957505/3933634

edycja: dzięki @zAlbee za ukończenie sugestii.

Liberateur
źródło
To jest dokładnie to, czego szukam, ale może nie działa to w związku z moją wersją mongo. obecny to 3,4?
Erce
Ktoś jeszcze dostaje TypeError: Object.bsonsize is not a function?
Félix Paradis
Czy próbowałeś w muszli mongo? To praca: docs.mongodb.com/manual/reference/mongo-shell/#miscellaneous
Liberateur
Właściwa etykieta byłaby raczej 'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024))(lub'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))
Wernfried Domscheit
31

Efektywna ilość miejsca, jaką dokument zajmie w kolekcji, będzie większa niż rozmiar dokumentu ze względu na mechanizm wypełniania rekordów .

Dlatego istnieje różnica między wyjściami funkcji db.test.stats()i Object.bsonsize(..).

Aby uzyskać dokładny rozmiar (w bajtach) dokumentu, trzymaj się Object.bsonsize()funkcji.

Konstantin Yovkov
źródło
Dziękuję za odpowiedź, w takim razie mam kolejne pytanie w tej sprawie: przypuśćmy, że mam zbiór, w którym zapisywane są dokumenty z długą listą identyfikatorów w postaci listy. (identyfikatory są przechowywane pierwotnie w pliku txt-csv - o rozmiarze 300 kB; każdy identyfikator ma 10 znaków) Kiedy uruchomię bsonsize na takim dokumencie, rozmiar jest nawet mniejszy niż 481. Zwraca 465. Czy możesz mi wyjaśnić tę sytuację, Proszę?
user1949763
4
Jaki rozmiar jest używany do egzekwowania ograniczenia rozmiaru dokumentu mongDB? Object.bsonsize ()?
John Evans,
Rozmiar dokumentu MongoDB jest ograniczeniem Mongo, jest to omówione w podręczniku na ich stronie internetowej, 16 MB. Osiągnąłem ten limit wiele razy, próbując importować rekordy.
htm11h
3

W mongodb 4.4 (w przygotowaniu) możesz użyć bsonSizeoperatora, aby uzyskać rozmiar dokumentu.

db.test.aggregate([
  {
    "$project": {
      "name": 1,
      "object_size": { "$bsonSize": "$$ROOT" }
    }
  }
])
Ashh
źródło
1

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

Visakh Vijayan
źródło
3
Spróbuj wyjaśnić swoją odpowiedź. .
Emmanuel Mtali