Jak uzyskać rozmiar pojedynczego dokumentu w Mongodb?

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:

  • obiekt.bsonsize - metoda javascript, która powinna zwracać rozmiar w bajtach
  • db.kolekcja.stats () - gdzie znajduje się linia 'avgObjSize', która tworzy pewien "zagregowany" (średni) widok wielkości na danych. Po prostu reprezentuje średnią wielkość jednolitego dokumentu.

  • Kiedy tworzę kolekcję testową tylko z jednym dokumentem, obie funkcje zwracają różne wartości. Jak to możliwe?
    Czy istnieje jakaś 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: type: "auto"

    db.test.insert({type:"auto"})
    
  2. Wyjście z wywołania funkcji stats() : db.test.statystyki():

    { 
      "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. Wyjście z funkcji bsonsize wywołania: obiekt.bsonsize (db.test.find({test: "auto"}))

    481
    
Author: ivanleoncz, 2014-02-25

5 answers

W poprzednim wywołaniu Object.bsonsize(), Mongodb zwrócił rozmiar kursora, a nie dokumentu.

Poprawnym sposobem jest użycie tego polecenia:

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

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

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

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

 182
Author: user1949763,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-28 19:58:13

Zalecałem użycie 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 skróci wartość ID podczas drukowania! Jeśli tak jest, możesz użyć zamiast tego:

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

To również ma tę zaletę, że zwraca JSON, więc GUI takie jak RoboMongo może go tabulować!

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

Edit: podziękowania dla @ zAlbee za Twoją sugestię.

 37
Author: Liberateur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:44

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 db.test.stats() i Object.bsonsize(..).

Aby uzyskać dokładny rozmiar (w bajtach) dokumentu, należy trzymać się funkcji Object.bsonsize().

 31
Author: Konstantin Yovkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 09:03:17

Z mongodb 4.4 (nadchodzące), można użyć bsonSize operator, aby uzyskać rozmiar dokumentu.

db.test.aggregate([
  {
    "$project": {
      "name": 1,
      "object_size": { "$bsonSize": "$$ROOT" }
    }
  }
])
 3
Author: Ashh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-27 05:17:35

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

 2
Author: Visakh Vijayan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-11 12:31:41