วิธีการรับขนาดของเอกสารเดียวใน Mongodb?


87

ฉันพบพฤติกรรมแปลก ๆ ของ mongo และฉันอยากจะชี้แจงมันสักหน่อย ...
คำขอของฉันง่ายมาก: ฉันต้องการรับเอกสารขนาดเดียวในคอลเลกชัน ฉันพบวิธีแก้ปัญหาที่เป็นไปได้สองวิธี:

  • Object.bsonsize - วิธีการจาวาสคริปต์บางอย่างที่ควรส่งคืนขนาดเป็นไบต์
  • db.collection.stats () - โดยที่มีบรรทัด "avgObjSize" ที่สร้างมุมมองขนาด "รวม" (ค่าเฉลี่ย) บางส่วนบนข้อมูล เป็นเพียงขนาดเฉลี่ยของเอกสารเดียว

  • เมื่อฉันสร้างคอลเล็กชันการทดสอบด้วยเอกสารเพียงชุดเดียวฟังก์ชันทั้งสองจะส่งคืนค่าที่แตกต่างกัน มันเป็นไปได้ยังไงกัน?
    มีวิธีอื่นในการรับขนาดของเอกสาร mongo หรือไม่?

ที่นี่ฉันให้รหัสบางส่วนที่ฉันทำการทดสอบ:

  1. ฉันสร้างฐานข้อมูลใหม่ 'ทดสอบ' และป้อนเอกสารอย่างง่ายด้วยแอตทริบิวต์เดียว: ประเภท: "auto"

    db.test.insert({type:"auto"})
    
  2. ผลลัพธ์จากการเรียกใช้ฟังก์ชัน 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. เอาต์พุตจากการเรียกฟังก์ชัน bsonsize: Object.bsonsize (db.test.find ({test: "auto"}))

    481
    

คำตอบ:


181

ในการเรียกครั้งก่อนObject.bsonsize()Mongodb ส่งคืนขนาดของเคอร์เซอร์แทนที่จะเป็นเอกสาร

วิธีที่ถูกต้องคือใช้คำสั่งนี้:

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

ด้วยfindOne()คุณสามารถกำหนดแบบสอบถามของคุณสำหรับเอกสารเฉพาะ:

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

สิ่งนี้จะส่งคืนขนาดที่ถูกต้อง (เป็นไบต์) ของเอกสารนั้น ๆ


1
จะรับขนาดของรายการเอกสารพร้อมแบบสอบถามได้อย่างไร?
ลีออน

แต่แน่นอนว่ารหัสนี้จะดึงเอกสารก่อนคำนวณขนาด
Sercan Ozdemir

สิ่งนี้ไม่ได้ส่งคืนขนาด goood: (... แต่สิ่งนี้: stackoverflow.com/a/40993183/3933634
Liberateur

4
จะรับ Object.bsonsize ได้อย่างไรคำสั่ง import หรือ required คืออะไร?
PARAMANANDA PRADHAN

8
สำหรับใครที่พลาดไปต้องใช้findOneแทนfind
แซม

36

ฉันแนะนำให้ใช้สคริปต์นี้เพื่อให้ได้ขนาดจริง

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

หมายเหตุ: หาก ID ของคุณเป็นจำนวนเต็ม 64 บิตข้างต้นจะตัดทอนค่า ID ในการพิมพ์! ในกรณีนี้คุณสามารถใช้แทน:

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

นอกจากนี้ยังมีข้อดีของการส่งคืน JSON ดังนั้น GUI เช่น RoboMongo จึงสามารถกำหนดตารางได้!

แหล่งที่มา: https://stackoverflow.com/a/16957505/3933634

แก้ไข: ขอบคุณ@zAlbeeสำหรับการแนะนำของคุณเสร็จสมบูรณ์


นี่คือสิ่งที่ฉันกำลังมองหา แต่มันใช้งานไม่ได้อาจเกี่ยวข้องกับเวอร์ชัน Mongo ของฉัน ปัจจุบันคือ 3.4?
Erce

มีใครรับอีกTypeError: Object.bsonsize is not a functionไหม
Félix Paradis

คุณลองใน mongo shell หรือไม่? ได้ผล: docs.mongodb.com/manual/reference/mongo-shell/#miscellaneous
Liberateur

ฉลากที่เหมาะสมจะค่อนข้างดี'KiB': Math.round(size/(1024)), 'MiB': Math.round(size/(1024*1024))(หรือ'kB': Math.round(size/(1000)), 'MB': Math.round(size/(1000*1000))
Wernfried Domscheit

31

จำนวนเนื้อที่ที่มีประสิทธิภาพที่เอกสารจะใช้ในคอลเลกชันจะมากกว่าขนาดของเอกสารของคุณเนื่องจากกลไกRecord Padding

นี่คือเหตุผลที่มีความแตกต่างระหว่างเอาต์พุตของdb.test.stats()และObject.bsonsize(..).

เพื่อให้ได้ขนาดที่แน่นอน (เป็นไบต์) ของเอกสารให้ปฏิบัติตามObject.bsonsize()ฟังก์ชัน


ขอบคุณสำหรับการตอบกลับของคุณในกรณีนี้ฉันมีคำถามอื่นเกี่ยวกับปัญหานี้: สมมติว่าฉันมีคอลเล็กชันที่มีการบันทึกเอกสารที่มีรายการตัวระบุแบบยาวไว้ในรูปแบบของรายการ (ตัวระบุถูกเก็บไว้เดิมในไฟล์ txt-csv - ขนาด 300 kB แต่ละตัวระบุยาว 10 ตัวอักษร) เมื่อฉันเรียกใช้bsonsizeบนเอกสารดังกล่าวขนาดจะต่ำกว่า 481 มันจะส่งกลับ 465 คุณช่วยอธิบายสถานการณ์นี้ให้ฉันฟังได้ไหม กรุณา?
user1949763

4
ขนาดใดที่ใช้บังคับข้อ จำกัด ขนาดเอกสาร mongDB Object.bsonsize ()?
John Evans

ขนาดเอกสาร MongoDB เป็นข้อ จำกัด ของ Mongo ซึ่งครอบคลุมอยู่ในคู่มือบนเว็บไซต์ 16MB ฉันได้ใช้ขีด จำกัด นี้หลายครั้งในการพยายามบันทึกการนำเข้า
htm11h

3

ด้วย mongodb 4.4 (กำลังจะมาถึง) คุณสามารถใช้bsonSizeตัวดำเนินการเพื่อรับขนาดเอกสาร

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.