Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

Upsert ใน MongoDB ด้วย Custom _id: Insert ถ้าไม่มี Error ถ้ามีอยู่แล้ว

เมื่อใช้ Custom _id (กำหนด _id เอง) การ insert() จะ error ถ้า _id ซ้ำ ต้องใช้ update() พร้อม upsert: true แทน

ปัญหาของ insert() กับ Custom _id

> db.customIdDemo.insert({ "_id": 1, "StudentName": "John" });
WriteResult({ "nInserted" : 1 })

> db.customIdDemo.insert({ "_id": 1, "StudentName": "Carol" });
// Error: E11000 duplicate key error collection: ... _id_ dup key: { : 1.0 }

วิธีแก้: ใช้ update() + upsert: true

db.collection.update(
    { _id: customId },
    { $set: { "field": "value" } },
    { upsert: true }
);

ตัวอย่าง: Custom _id แบบตัวเลข

1. Insert ครั้งแรก (สำเร็จ)

> db.customIdDemo.insert({ "_id": 1, "StudentName": "John" });
WriteResult({ "nInserted" : 1 })

2. Insert ซ้ำ _id = 1 (Error)

> db.customIdDemo.insert({ "_id": 1, "StudentName": "Carol" });
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error..." } })

3. ใช้ Upsert แทน (ไม่ Error)

> db.customIdDemo.update(
    { "_id": 1 },
    { $set: { "StudentName": "Carol" } },
    { upsert: true }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

4. Insert ใหม่ _id = 2 (Upsert)

> db.customIdDemo.update(
    { "_id": 2 },
    { $set: { "StudentName": "Carol" } },
    { upsert: true }
);
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 2 })

5. ผลลัพธ์สุดท้าย

> db.customIdDemo.find().pretty();
{ "_id" : 1, "StudentName" : "Carol" }   // Updated
{ "_id" : 2, "StudentName" : "Carol" }   // Inserted

สรุปความแตกต่าง

Method_id ซ้ำ_id ใหม่
insert()Error (E11000)Success
update({}, {upsert:true})Update (Safe)Insert (Safe)

Best Practice

  • ใช้ updateOne() + upsert: true แทน insert() เมื่อมี Custom _id
  • สร้าง Unique Index บน _id (มีอยู่โดยอัตโนมัติ)
  • ใน Application ใช้ findOneAndUpdate() พร้อม upsert: true สำหรับ atomic read-modify-write