อัพเดต Mongodb ด้วย upsert และหลายไวยากรณ์

ฉันยังใหม่กับ mongodb และเครียดมากเพราะเอกสารที่ไม่สมบูรณ์ของ mongodb ทำให้ฉันต้องลองผิดลองถูก... น่าเศร้าที่ความพยายามทั้งหมดของฉันไม่ได้ทำงานโดยไม่มีข้อผิดพลาด ทำให้ฉันสับสนเกี่ยวกับสิ่งที่เกิดขึ้นและสิ่งที่ต้องแก้ไข...

ฉันแค่ต้องอัปเดตหลายบันทึกในฐานข้อมูลที่ตรงกับเกณฑ์ที่กำหนด และสำหรับบันทึกที่ไม่มีอยู่ ให้สร้างรายการใหม่สำหรับสิ่งนั้น ฉันเชื่อว่าฉันสามารถทำได้ด้วยการเข้าถึงฐานข้อมูลเดียวพร้อมการอัพเดต upsert และหลายรายการ นี่คือสิ่งที่ฉันได้เกิดขึ้น:

dbschema.Person.update( { person_id: { $in: ["734533604" ,"701084015"] } }, { $set: {"scores": 1200} }, { options: { upsert: true, multi: true } } );

ฉันได้ลองใช้ชุดค่าผสมหลายชุดหรือแม้แต่เวอร์ชันเก่าเช่น:

dbschema.Person.update( { person_id: { $in: ["734533604" ,"701084015"] } }, { $set: {"scores": 1200} }, { upsert: true }, { multi: true } );

ไม่ทำงานเลย...

โปรดช่วยฉันในเรื่องเล็กน้อยนี้ด้วย ... ฉันสามารถทำมันได้อย่างง่ายดายใน sql แต่สิ่งที่ nosql นั้นจำกัดฉันมาก .. ขอบคุณ!

แก้ไข:

แบบสอบถามเดียวกันในการค้นหาทำงานได้อย่างสมบูรณ์:

dbschema.Person.find( { person_id: { $in: ["734533604" ,"701084015"] } }, function ( err, results ) {
    console.log( 'result: ' + results );
    console.log( 'error: ' + err );
    console.log( 'result length: ' + results.length );
} );

แก้ไข:

ฉันคาดหวังว่าจะสร้างบันทึก "ไม่พบ" และบันทึกที่พบจะได้รับการอัปเดต ตรรกะของฉันอาจมีข้อบกพร่อง และตอนนี้ฉันก็สับสนมาก

เดิมที ฉันค้นหา()-ing ครั้งละหนึ่งระเบียน เปลี่ยนค่า และเรียกว่า save() สำหรับแต่ละระเบียนที่แก้ไข แต่เมื่อฉันนำไปใช้งานจริง เวลาตอบสนองจะช้าลงหลายร้อยเท่า โดยเฉพาะอย่างยิ่งเมื่อมี มีการอัปเดตบันทึกไม่กี่ร้อยรายการในแต่ละคำขอ

จากนั้นฉันก็พบ find() + $in และประสิทธิภาพได้รับการกู้คืนและดียิ่งขึ้นกว่าเดิม (เมื่อทำการสืบค้น) แต่การอัปเดตยังคงช้าอย่างไม่อาจยอมรับได้.. ดังนั้นตอนนี้ฉันกำลังมองหาวิธีในการอัปเดตเอกสารทั้งหมดในแบบสอบถามเดียว .

สิ่งที่ฉันทำตามปกติใน SQL คือการใช้ UPDATE WHEN CASE THEN... เช่น:

UPDATE person SET score = CASE
WHEN person_id = "734533604" THEN 1200
WHEN person_id = "701084015" THEN 1200
ELSE
score
END

person Zennichimaro    schedule 01.05.2013    source แหล่งที่มา
comment
มันเป็นไปไม่ได้ที่จะใช้ upsert กับ $in เพราะ upsert สามารถแทรกได้ครั้งละหนึ่งรหัส และมันจะสับสนระหว่างค่าแรกและค่าที่สอง   -  person Ajay Beniwal    schedule 01.05.2013
comment
คุณมีปัญหาหลายประการ บางอย่างเกี่ยวกับวากยสัมพันธ์แต่ปัญหาอื่นๆ เกิดจากการออกแบบ หากคุณกำลังมองหา 2 บันทึกที่ตรงกันแต่ไม่พบ คุณคาดหวังว่าจะสร้างทั้งสองรายการหรือไม่? หากพบหนึ่งในสองรายการ คุณคาดหวังว่าจะมีการอัปเดตรายการใดรายการหนึ่งและสร้างรายการใหม่ขึ้นมาหรือไม่ Upsert สามารถสร้างสถิติใหม่ได้มากสุดเพียง 1 รายการ และนี่คือเหตุผลว่าทำไมบางครั้ง Multi และ Upsert จึงไม่เหมาะสมกัน   -  person Asya Kamsky    schedule 02.05.2013
comment
ใช่ ฉันคาดหวังว่าทั้งคู่จะถูกสร้างขึ้นหากไม่พบ หากพบสิ่งใดสิ่งหนึ่ง จะต้องได้รับการอัปเดต และส่วนที่ไม่พบจะถูกสร้างขึ้น... คุณพูดถูก ฉันสับสนมาก และบางทีตรรกะของฉันก็อาจมีข้อบกพร่องเช่นกัน .. แต่ฉันจะอธิบายว่าทำไมฉันถึงพยายามทำเช่นนี้ ..   -  person Zennichimaro    schedule 02.05.2013


คำตอบ (1)


คุณไม่สามารถอัปเดตหลายระเบียนตามเกณฑ์ที่แตกต่างกันได้ และคาดหวังว่า "upsert" จะเข้าใจว่าคุณหมายถึงอะไร การตั้งค่าสถานะ Upsert อาจทำให้เกิดการแทรกเอกสารได้มากที่สุด 1 รายการ และหากคุณตรวจสอบเอกสารประกอบ คุณจะเห็นว่าการมีเกณฑ์ "ผสม" สำหรับการอัปเดตในกรณีที่มีการอัปโหลดนั้นไม่สมเหตุสมผล

ในตัวอย่างของคุณ ค่า fbid ทั้งสองค่าที่แทรกควรใช้ค่าใด

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

นี่คือคำอธิบายเกี่ยวกับวิธีการทำงานของการอัปเดต - ฉันพบว่ามันค่อนข้างสมบูรณ์: http://docs.mongodb.org/manual/core/update/#update-operations-with-the-upsert-flag

person Asya Kamsky    schedule 01.05.2013
comment
ขอบคุณ ฉันคาดหวังว่าบันทึกทั้งหมดใน $in จะได้รับการอัปเดตหรือแทรก ฉันไม่แน่ใจว่านี่เป็นวิธีที่จะทำได้หรือไม่ เนื่องจากฉันพยายามเพิ่มประสิทธิภาพการแทรก/การอัปเดตจำนวนมากที่ทำให้เวลาตอบสนองของฉันลดลง คุณมีความคิดบ้างไหมว่าฉันสามารถแทรก/อัปเดตบันทึกจำนวนมากและบันทึกไว้ในช็อตเดียวได้อย่างไร - person Zennichimaro; 02.05.2013
comment
ไม่มีทางที่จะทำเช่นนั้นได้ ถ้าฉันเข้าใจคำถามของคุณ - person Asya Kamsky; 02.05.2013
comment
ลิงค์หายไป 404. - person luckydonald; 15.10.2018
comment
ขอบคุณ. ตอนนี้ได้รับการแก้ไขแล้ว - person Asya Kamsky; 17.10.2018