Bagaimana cara mendapatkan ukuran satu dokumen di Mongodb?

87

Saya menemukan perilaku mongo yang aneh dan saya ingin menjelaskannya sedikit ...
Permintaan saya sesederhana itu: Saya ingin mendapatkan satu ukuran dokumen dalam koleksi. Saya menemukan dua solusi yang mungkin:

  • Object.bsonsize - beberapa metode javascript yang harus mengembalikan ukuran dalam byte
  • db.collection.stats () - di mana ada baris 'avgObjSize' yang menghasilkan beberapa tampilan ukuran "agregat" (rata-rata) pada data. Ini hanya mewakili ukuran rata-rata dari satu dokumen.

  • Saat saya membuat koleksi pengujian dengan hanya satu dokumen, kedua fungsi mengembalikan nilai yang berbeda. Bagaimana itu mungkin?
    Apakah ada metode lain untuk mendapatkan ukuran dokumen mongo?

Di sini, saya memberikan beberapa kode yang saya uji:

  1. Saya membuat 'test' database baru dan memasukkan dokumen sederhana dengan hanya satu atribut: type: "auto"

    db.test.insert({type:"auto"})
    
  2. keluaran dari pemanggilan fungsi 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. keluaran dari panggilan fungsi bsonsize: Object.bsonsize (db.test.find ({test: "auto"}))

    481
    
pengguna1949763
sumber

Jawaban:

181

Dalam panggilan sebelumnya Object.bsonsize(), Mongodb mengembalikan ukuran kursor, bukan dokumennya.

Cara yang benar adalah dengan menggunakan perintah ini:

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

Dengan findOne(), Anda dapat menentukan kueri Anda untuk dokumen tertentu:

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

Ini akan mengembalikan ukuran yang benar (dalam byte) dari dokumen tertentu.

pengguna1949763
sumber
1
Bagaimana cara mendapatkan ukuran daftar dokumen dengan query?
leon
Namun tentunya kode ini akan mengambil dokumen sebelum menghitung ukurannya.
Sercan Ozdemir
Ini tidak mengembalikan ukuran yang bagus: (... Tapi ini: stackoverflow.com/a/40993183/3933634
Liberateur
4
Bagaimana cara mendapatkan Object.bsonsize, apa pernyataan import atau required?
PARAMANANDA PRADHAN
8
Untuk orang lain yang tidak terjawab itu, Anda harus menggunakan findOnebukannyafind
Sam
36

Saya merekomendasikan untuk menggunakan skrip ini untuk mendapatkan ukuran sebenarnya.

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

Catatan: Jika ID Anda adalah bilangan bulat 64-bit, di atas akan memotong nilai ID saat dicetak! Jika demikian, Anda dapat menggunakan:

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

Ini juga memiliki keuntungan mengembalikan JSON, sehingga GUI seperti RoboMongo dapat mentabulasikannya!

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

edit: terima kasih kepada @zAlbee atas saran Anda selesai.

Liberateur
sumber
Ini persis seperti yang saya cari tetapi tidak berfungsi mungkin terkait dengan versi mongo saya. saat ini adalah 3.4?
Erce
Ada lagi yang mendapatkan TypeError: Object.bsonsize is not a function?
Félix Paradis
Apakah Anda sudah mencobanya di mongo shell? Ini berhasil: docs.mongodb.com/manual/reference/mongo-shell/#miscellaneous
Liberateur
Label yang tepat akan lebih baik 'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024))(atau'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))
Wernfried Domscheit
31

Jumlah efektif ruang dokumen yang akan diambil dalam koleksi akan lebih dari ukuran dokumen Anda karena mekanisme Padding Rekaman .

Inilah sebabnya mengapa ada perbedaan antara keluaran dari db.test.stats()dan Object.bsonsize(..).

Untuk mendapatkan ukuran yang tepat (dalam byte) dari dokumen, tetap gunakan Object.bsonsize()fungsinya.

Konstantin Yovkov
sumber
Terima kasih atas balasan Anda, dalam hal ini saya punya pertanyaan lain mengenai masalah ini: misalkan saya memiliki koleksi di mana dokumen dengan daftar panjang pengenal disimpan dalam bentuk daftar. (pengidentifikasi awalnya disimpan dalam file txt-csv- dengan ukuran 300 kB; masing-masing pengenal memiliki panjang 10 karakter) Ketika saya menjalankan bsonsize pada dokumen semacam itu, ukurannya bahkan lebih rendah dari 481. Ia mengembalikan 465. Bisakah Anda menjelaskan kepada saya situasi ini, silahkan?
pengguna1949763
4
Ukuran apa yang digunakan untuk memberlakukan batasan ukuran dokumen mongDB? Object.bsonsize ()?
John Evans
Ukuran dokumen MongoDB adalah batasan dari Mongo, ini tercakup dalam manual di situs web mereka, 16MB. Saya telah mencapai batas ini beberapa kali mencoba mengimpor catatan.
htm11h
3

Dengan mongodb 4.4 (mendatang), Anda dapat menggunakan bsonSizeoperator untuk mendapatkan ukuran dokumen.

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

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

Visakh Vijayan
sumber
3
Cobalah untuk menjelaskan jawaban Anda. .
Emmanuel Mtali