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

วิธี Upsert ใน MongoDB: Insert ถ้าไม่มี Update ถ้ามีอยู่แล้ว (Unique Value)

ใช้ Upsert (Update + Insert) ด้วย option { upsert: true } ในคำสั่ง update() เพื่อ Insert ใหม่ถ้ายังไม่มี หรือ Update ถ้ามีอยู่แล้ว

รูปแบบคำสั่ง

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

ตัวอย่างเต็มรูปแบบ

1. สร้างข้อมูลเริ่มต้น

> db.onlyInsertIfValueIsUniqueDemo.insertOne({"StudentName":"Larry","StudentAge":22});
> db.onlyInsertIfValueIsUniqueDemo.insertOne({"StudentName":"Mike","StudentAge":21});
> db.onlyInsertIfValueIsUniqueDemo.insertOne({"StudentName":"Sam","StudentAge":24});

Case 1: ค่ามีอยู่แล้ว → Update (Mike อายุ 21 → 27)

> db.onlyInsertIfValueIsUniqueDemo.update(
    { StudentName: "Mike" },
    { $set: { "StudentAge": 27 } },
    { upsert: true }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

ผลลัพธ์: nMatched=1, nUpserted=0, nModified=1 → Update

{ "_id" : ..., "StudentName" : "Mike", "StudentAge" : 27 }  // อายุเปลี่ยน

Case 2: ค่ายังไม่มี → Insert ใหม่ (David)

> db.onlyInsertIfValueIsUniqueDemo.update(
    { StudentName: "David" },
    { $set: { "StudentAge": 25 } },
    { upsert: true }
);
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : ObjectId("...") })

ผลลัพธ์: nMatched=0, nUpserted=1, nModified=0 → Insert ใหม่ (มี _id ใหม่)

{ "_id" : ..., "StudentName" : "David", "StudentAge" : 25 }  // เพิ่มใหม่

WriteResult Fields ความหมาย

Fieldความหมาย
nMatchedจำนวนเอกสารที่ match query
nUpsertedจำนวนเอกสารที่ insert ใหม่ (0 หรือ 1)
nModifiedจำนวนเอกสารที่แก้ไขจริง
_id_id ของเอกสารที่ insert ใหม่ (กรณี upsert)

วิธีสมัยใหม่ (MongoDB 3.2+)

// updateOne - upsert เดียว
db.collection.updateOne(
    { StudentName: "David" },
    { $set: { StudentAge: 25 } },
    { upsert: true }
);

// replaceOne - แทนที่ทั้งเอกสาร
db.collection.replaceOne(
    { StudentName: "David" },
    { StudentName: "David", StudentAge: 25 },
    { upsert: true }
);

สรุป

  • upsert: true = Insert ถ้าไม่เจอ, Update ถ้าเจอ
  • เหมาะสำหรับ "Insert if not exists, otherwise update"
  • ต้องมี Unique Index บนฟิลด์ query เพื่อป้องกัน duplicate race condition
  • คืนค่า WriteResult บอกว่าเป็น Insert หรือ Update