อะไรคือความแตกต่างระหว่าง findAndModify และอัปเดตใน MongoDB?


175

ฉันสับสนเล็กน้อยกับfindAndModifyวิธีการใน MongoDB ข้อดีของupdateวิธีนี้คืออะไร? สำหรับฉันดูเหมือนว่าเพิ่งส่งคืนสินค้าก่อนแล้วจึงอัปเดต แต่ทำไมฉันต้องคืนสินค้าก่อน? ฉันอ่านMongoDB: คำแนะนำที่ชัดเจนและมันบอกว่ามันมีประโยชน์สำหรับการจัดการกับคิวและการดำเนินการอื่น ๆ ที่ต้องการอะตอมมิกซิตี้สไตล์แบบ Get-and-Set แต่ฉันไม่เข้าใจว่ามันบรรลุสิ่งนี้ได้อย่างไร ใครสามารถอธิบายสิ่งนี้ให้ฉันได้บ้าง

คำตอบ:


153

หากคุณดึงรายการแล้วอัปเดตอาจมีการอัปเดตโดยเธรดอื่นระหว่างสองขั้นตอนเหล่านั้น หากคุณอัปเดตไอเท็มก่อนจากนั้นดึงออกมาอาจมีการอัปเดตอื่น ๆ อยู่ระหว่างนั้นและคุณจะได้รับไอเท็มที่แตกต่างจากสิ่งที่คุณอัปเดต

การทำ "atomically" หมายความว่าคุณรับประกันว่าคุณได้รับคืนรายการเดิมที่คุณกำลังอัพเดท - นั่นคือไม่มีการดำเนินการอื่นใดเกิดขึ้นระหว่างนั้น


6
ฉันยังคงสับสนเล็กน้อย จะfindAndModifyรับประกันได้อย่างไรว่าไม่มีการดำเนินการอัพเดตอื่นรบกวน
chaonextdoor

78
@chaonextdoor findAndModify ได้รับการล็อคไปยังฐานข้อมูลเมื่อมันเริ่มการดำเนินการเพื่อให้ไม่มีการดำเนินการอื่นสามารถดำเนินการเมื่อมันกำลังทำงาน เมื่อเสร็จสิ้นการดำเนินการมันจะปลดล็อค
Lycha

4
findAndModify ไม่ได้รับการล็อคจริงจนกว่าส่วนการเปลี่ยนแปลงของคำขอ ดังนั้นจึงเป็นไปได้ที่กระบวนการหลายอย่างจะสามารถปรับปรุงระเบียนเดียวกัน
ทำเครื่องหมาย Unsworth

5
@ MarkUnsworth เปิดกรณีการสนับสนุนด้วย 10gen - หากมีข้อผิดพลาดในการล็อคด้วย findAndModify ฉันสามารถรับประกันได้ว่าคุณวิศวกรต้องการแก้ไขโดยเร็ว หากเป็นเช่นนั้นแม้ว่าเราจะเห็นคนจำนวนมากรายงานพฤติกรรมนี้ แต่ findAndModify ทำงานตามที่ออกแบบมาสำหรับทุกคนที่ใช้งาน - กรณีที่ดูเหมือนว่ามันไม่ได้เกิดจากตรรกะหรือข้อบกพร่องในการใช้งานด้านลูกค้า แต่แน่นอนในซอฟต์แวร์ที่ซับซ้อนอาจมีข้อผิดพลาด
Asya Kamsky

4
@ AsyaKamsky ฉันกำลังพิจารณาเรื่องการโต้เถียงกับคุณ แต่แล้วฉันก็รู้ว่าคุณถูกต้องแล้วตอนนี้ฉันคิดว่าฉันควรจะขอโทษ ขออภัย!
funkyeah

54

findAndModify ส่งคืนเอกสารการอัพเดตไม่

ถ้าผมเข้าใจ Dwight Merriman (หนึ่งในนักเขียนที่เป็นต้นฉบับของ MongoDB) ได้อย่างถูกต้องโดยใช้การอัปเดตการปรับเปลี่ยนเอกสารฉบับเดียวคือ ( "หลาย":. เท็จ} findAndModifyยังเป็นอะตอมในปัจจุบันก็ยังควรจะเร็วกว่าการทำการปรับปรุงโดยใช้เทียบเท่า


31

จากMongoDB เอกสาร (เน้นเพิ่ม):

  • โดยค่าเริ่มต้นการดำเนินงานทั้งสองแก้ไขเอกสารเดียว อย่างไรก็ตามเมธอด update () พร้อมตัวเลือกหลายตัวสามารถแก้ไขเอกสารได้มากกว่าหนึ่งฉบับ

  • หากเอกสารหลายฉบับตรงกับเกณฑ์การอัปเดตสำหรับ findAndModify () คุณสามารถระบุการจัดเรียงเพื่อจัดเตรียมการวัดการควบคุมบางอย่างสำหรับเอกสารที่จะอัปเดต ด้วยพฤติกรรมเริ่มต้นของวิธีการ update () คุณไม่สามารถระบุเอกสารเดี่ยวที่จะอัปเดตเมื่อเอกสารหลายฉบับตรงกัน

  • โดยค่าเริ่มต้น findAndModify () วิธีการส่งกลับรุ่นก่อนแก้ไขของเอกสาร หากต้องการรับเอกสารที่อัพเดตให้ใช้ตัวเลือกใหม่ การปรับปรุง () วิธีการส่งกลับวัตถุ WriteResult ที่มีสถานะของการดำเนินการ หากต้องการส่งคืนเอกสารที่อัพเดตให้ใช้วิธีค้นหา () อย่างไรก็ตามการปรับปรุงอื่น ๆ อาจมีการปรับเปลี่ยนเอกสารระหว่างการปรับปรุงและการดึงเอกสารของคุณ นอกจากนี้หากการอัปเดตแก้ไขเพียงเอกสารเดียว แต่เอกสารหลายฉบับตรงกันคุณจะต้องใช้ตรรกะเพิ่มเติมเพื่อระบุเอกสารที่อัปเดต

  • ก่อน MongoDB 3.2 คุณไม่สามารถระบุข้อกังวลการเขียนเพื่อ findAndModify () เพื่อแทนที่ข้อกังวลการเขียนเริ่มต้นในขณะที่คุณสามารถระบุข้อกังวลการเขียนไปยังวิธีการ update () ตั้งแต่ MongoDB 2.6

เมื่อแก้ไขเอกสารเดี่ยวทั้ง findAndModify () และเมธอด update () จะอัพเดตเอกสารแบบ atom


1
คุณสามารถระบุข้อกังวลการเขียนเพื่ออัปเดตการดำเนินการได้ตลอดเวลา นอกจากนี้ตั้งแต่ 3.2 (3.1.1 ทางเทคนิค) คุณสามารถระบุข้อกังวลการเขียนเพื่อ findAndModify เช่นกัน jira.mongodb.org/browse/SERVER-6558
Asya Kamsky

ฉันได้พบว่าใน MongDB 3.6 แม้ว่ารัฐ doc findAndModify()โดยปรับเปลี่ยนค่าเริ่มต้น doc เดียวupdate()สามารถอัปเดตหนึ่งหรือเอกสารอื่น ๆ เมื่อผมใช้arrayFilters, findAndModify()การปรับปรุงการแข่งขันทั้งหมด อาจเป็นข้อผิดพลาดหรือไม่?
WesternGun

ไม่มีข้อผิดพลาด - arrayFilters อนุญาตให้คุณอัปเดตองค์ประกอบหลายชุด แต่ยังคงอยู่ในเอกสารเดียว
Asya Kamsky

10

คลาสการใช้งานที่มีประโยชน์อย่างหนึ่งคือตัวนับและเคสที่คล้ายกัน ยกตัวอย่างเช่นดูที่รหัสนี้ (หนึ่งในการทดสอบ MongoDB) A: find_and_modify4.js

ดังนั้นเมื่อfindAndModifyคุณเพิ่มตัวนับและรับค่าที่เพิ่มขึ้นในขั้นตอนเดียว เปรียบเทียบ: หากคุณ (A) ดำเนินการนี้ในสองขั้นตอนและบุคคลอื่น (B) ดำเนินการเดียวกันระหว่างขั้นตอนของคุณ A และ B อาจได้รับค่าตัวนับสุดท้ายเหมือนกันแทนที่จะเป็นสองประเด็นที่แตกต่างกัน


0

เราใช้ findAndModify () สำหรับการทำงานของตัวนับ (inc หรือ dec) และฟิลด์เดี่ยวอื่น ๆ กลายพันธุ์เคส การโยกย้ายแอปพลิเคชันของเราจาก Couchbase ไปยัง MongoDB ฉันพบ API นี้เพื่อแทนที่รหัสที่ใช้ GetAndlock (), แก้ไขเนื้อหาในเครื่อง, แทนที่ () เพื่อบันทึกและรับ () อีกครั้งเพื่อดึงเอกสารที่อัปเดตกลับ ด้วย mongoDB ฉันใช้ API นี้เดียวซึ่งส่งคืนเอกสารที่อัปเดต

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