MongoDB เรียงลำดับระเบียนอย่างไรเมื่อไม่มีการระบุลำดับการจัดเรียง


103

เมื่อเราเรียกใช้แบบสอบถาม Mongo find () โดยไม่ระบุลำดับการจัดเรียงใด ๆ ฐานข้อมูลภายในใช้อะไรในการจัดเรียงผลลัพธ์

ตามเอกสารในเว็บไซต์ mongo :

เมื่อดำเนินการ find () โดยไม่มีพารามิเตอร์ฐานข้อมูลจะส่งคืนอ็อบเจ็กต์ตามลำดับธรรมชาติไปข้างหน้า

สำหรับตารางมาตรฐานคำสั่งธรรมชาติไม่ได้มีประโยชน์อย่างยิ่งเนื่องจากแม้ว่าคำสั่งดังกล่าวมักจะใกล้เคียงกับลำดับการแทรก แต่ก็ไม่รับประกันว่าจะเป็น อย่างไรก็ตามสำหรับคอลเลกชันที่มีการต่อยอดจะรับประกันว่าลำดับตามธรรมชาติจะเป็นลำดับการแทรก สิ่งนี้จะมีประโยชน์มาก

อย่างไรก็ตามสำหรับคอลเลกชันมาตรฐาน (คอลเลกชันที่ไม่ได้ต่อยอด) ฟิลด์ใดที่ใช้ในการเรียงลำดับผลลัพธ์ มันเป็นฟิลด์_idหรืออย่างอื่น?

แก้ไข:

โดยทั่วไปฉันเดาว่าสิ่งที่ฉันพยายามจะได้รับคือถ้าฉันดำเนินการค้นหาต่อไปนี้:

db.collection.find({"x":y}).skip(10000).limit(1000);

ในเวลาสองจุดที่แตกต่างกัน: t1และt2ฉันจะได้รับชุดผลลัพธ์ที่ต่างกันหรือไม่:

  1. เมื่อไม่มีการเขียนเพิ่มเติมระหว่าง t1 & t2?
  2. เมื่อมีการเขียนใหม่ระหว่าง t1 และ t2?
  3. มีดัชนีใหม่ที่ถูกเพิ่มระหว่าง t1 & t2?

ฉันได้ทำการทดสอบในฐานข้อมูลชั่วคราวและผลลัพธ์ที่ได้ก็เหมือนกัน ( ใช่ ) สำหรับทั้ง 3 กรณี - แต่ฉันต้องการความแน่ใจและฉันมั่นใจว่ากรณีการทดสอบของฉันไม่ละเอียดถี่ถ้วน

คำตอบ:


120

ลำดับการจัดเรียงเริ่มต้นคืออะไรเมื่อไม่มีการระบุ

ลำดับการจัดเรียงภายในเริ่มต้น (หรือลำดับธรรมชาติ ) คือรายละเอียดการใช้งานที่ไม่ได้กำหนดไว้ เพื่อการดูแลรักษาเป็นค่าใช้จ่ายเพิ่มเติมสำหรับเครื่องมือการจัดเก็บและ API MongoDB ไม่อาณัตินอกการคาดการณ์ของอย่างชัดเจนsort()หรือกรณีพิเศษคงที่ขนาดคอลเลกชันที่ปกคลุมซึ่งได้เชื่อมโยงข้อ จำกัด การใช้ สำหรับเวิร์กโหลดทั่วไปเป็นที่พึงปรารถนาสำหรับเอ็นจินหน่วยเก็บข้อมูลที่จะพยายามนำพื้นที่ที่จัดสรรไว้ล่วงหน้าที่มีอยู่กลับมาใช้ใหม่และตัดสินใจเกี่ยวกับวิธีการจัดเก็บข้อมูลอย่างมีประสิทธิภาพสูงสุดบนดิสก์และในหน่วยความจำ

หากไม่มีเกณฑ์การค้นหาใด ๆ ผลลัพธ์จะถูกส่งกลับโดยเอ็นจินการจัดเก็บตามลำดับธรรมชาติ (aka ตามลำดับที่พบ ) ลำดับผลลัพธ์อาจตรงกับลำดับการแทรก แต่ไม่รับประกันพฤติกรรมนี้และไม่สามารถพึ่งพาได้ (นอกเหนือจากคอลเลกชันที่ต่อยอด)

ตัวอย่างบางส่วนที่อาจส่งผลต่อลำดับการจัดเก็บ (ตามธรรมชาติ):

  • WiredTiger ใช้การแสดงเอกสารบนดิสก์ที่แตกต่างกันเมื่อเทียบกับแคชในหน่วยความจำดังนั้นลำดับตามธรรมชาติอาจเปลี่ยนแปลงไปตามโครงสร้างข้อมูลภายใน
  • เอ็นจินหน่วยเก็บ MMAPv1 ดั้งเดิม (ลบออกใน MongoDB 4.2) จัดสรรพื้นที่บันทึกสำหรับเอกสารตามกฎการเติม หากเอกสารมีขนาดใหญ่กว่าพื้นที่บันทึกที่จัดสรรในปัจจุบันตำแหน่งของเอกสาร (และลำดับตามธรรมชาติ) จะได้รับผลกระทบ นอกจากนี้ยังสามารถแทรกเอกสารใหม่ในพื้นที่จัดเก็บที่ระบุว่าพร้อมใช้งานซ้ำได้เนื่องจากเอกสารที่ถูกลบหรือย้าย
  • การจำลองแบบใช้รูปแบบoplog idempotentเพื่อใช้การดำเนินการเขียนอย่างสม่ำเสมอในสมาชิกชุดแบบจำลอง สมาชิกชุดข้อมูลจำลองแต่ละชุดจะเก็บรักษาไฟล์ข้อมูลในเครื่องซึ่งอาจแตกต่างกันไปตามลำดับตามธรรมชาติ แต่จะมีผลลัพธ์ข้อมูลเหมือนกันเมื่อใช้การอัปเดต oplog

จะเกิดอะไรขึ้นถ้าใช้ดัชนี?

หากใช้ดัชนีเอกสารจะถูกส่งคืนตามลำดับที่พบ (ซึ่งจำเป็นต้องตรงกับลำดับการแทรกหรือลำดับ I / O) หากมีการใช้ดัชนีมากกว่าหนึ่งรายการลำดับจะขึ้นอยู่กับว่าดัชนีใดระบุเอกสารเป็นอันดับแรกในระหว่างขั้นตอนการคัดลอก

หากคุณต้องการลำดับการจัดเรียงที่คาดเดาได้คุณจะต้องใส่ข้อมูลที่ชัดเจนในsort()คำค้นหาของคุณและมีค่าเฉพาะสำหรับคีย์การจัดเรียงของคุณ

คอลเลกชันที่ต่อยอดจะรักษาลำดับการแทรกได้อย่างไร

ข้อยกเว้นการใช้งานที่ระบุไว้สำหรับลำดับตามธรรมชาติในคอลเลกชันที่ต่อยอดถูกบังคับใช้โดยข้อ จำกัด การใช้งานพิเศษ: เอกสารจะถูกจัดเก็บตามลำดับการแทรก แต่ไม่สามารถเพิ่มขนาดเอกสารที่มีอยู่และไม่สามารถลบเอกสารได้อย่างชัดเจน การสั่งซื้อเป็นส่วนหนึ่งของการออกแบบคอลเลกชันที่ต่อยอดเพื่อให้แน่ใจว่าเอกสารที่เก่าที่สุด "หมดอายุ" ก่อน


4
นั่นหมายความว่าถ้าฉันเรียกใช้คำสั่ง find เดียวกัน: db.collection.find ({"x": y}). ข้าม (20000) .limit (1000) ในเวลาที่ต่างกันสองจุดฉันจะได้ผลลัพธ์ที่ต่างกัน ชุด? จะเกิดอะไรขึ้นถ้าไม่มีการเขียนระหว่างสองคำสั่ง?
saurabhj

6
@saurabhj: เพิ่มตัวอย่างบางส่วนที่จะส่งผลต่อระเบียบธรรมชาติ หากเอกสารถูกย้าย / ลบคุณอาจได้รับชุดผลลัพธ์ที่แตกต่างกัน หากไม่มีการแทรก / อัปเดต / ลบเอกสารคุณควรได้รับผลลัพธ์เดียวกัน การเพิ่มดัชนีไม่มีผลต่อตำแหน่งของเอกสารบนดิสก์
Stennie

7
นอกจากนี้ควรเพิ่มข้อแม้ว่าหากคุณใช้การจำลองแบบลำดับตามธรรมชาติอาจแตกต่างกันไประหว่างสมาชิกชุดการจำลอง
Stennie

ไม่มีใครรู้วิธีบังคับ 2 คะแนนที่แสดงความคิดเห็นที่นี่? เราพยายามแก้ไขเอกสาร แต่ยังคงส่งคืนตามลำดับการแทรก ... ฉันสงสัยว่าลำดับธรรมชาติอาจแตกต่างจากลำดับการแทรกหรือไม่
Ferran Maylinch

การบังคับใช้คำสั่งเริ่มต้น (เช่น{createdAt: -1}) จำเป็นต้องใช้รูปแบบ Optimistic UI (อัปเดตรายการข้อมูลในแคชโดยไม่ต้องรอการตอบสนองของเซิร์ฟเวอร์หลังจากสร้าง / อัปเดต / ลบ) มิฉะนั้นคุณจะไม่สามารถจับคู่คำสั่งในแง่ดีของฝั่งไคลเอ็นต์และลำดับการตอบกลับของเซิร์ฟเวอร์ได้
Eric Burel

8

จะถูกส่งคืนตามลำดับที่จัดเก็บ (ลำดับในไฟล์) แต่ไม่รับประกันว่าจะอยู่ในลำดับที่แทรก ไม่ได้จัดเรียงตามฟิลด์ _id บางครั้งอาจดูเหมือนจัดเรียงตามลำดับการแทรก แต่สามารถเปลี่ยนแปลงได้ในคำขออื่น มันไม่น่าเชื่อถือ

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