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:
Utworzyłem nową bazę danych „test” i wprowadziłem prosty dokument z tylko jednym atrybutem: typ: „auto”
db.test.insert({type:"auto"})
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
}
dane wyjściowe wywołania funkcji bsonsize: Object.bsonsize (db.test.find ({test: "auto"}))
481
źródło
findOne
zamiastfind
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.
źródło
TypeError: Object.bsonsize is not a function
?'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024))
(lub'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))
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()
iObject.bsonsize(..)
.Aby uzyskać dokładny rozmiar (w bajtach) dokumentu, trzymaj się
Object.bsonsize()
funkcji.źródło
W mongodb 4.4 (w przygotowaniu) możesz użyć
bsonSize
operatora, aby uzyskać rozmiar dokumentu.db.test.aggregate([ { "$project": { "name": 1, "object_size": { "$bsonSize": "$$ROOT" } } } ])
źródło
Object.bsonsize (db.test.findOne ({type: "auto"})) Daje w bajtach.
źródło