การใช้ $set ร่วมกับตัวเลือก upsert: true ช่วยให้สามารถอัปเดตเอกสารที่มีอยู่ หรือสร้างใหม่หากไม่พบเอกสารที่ตรงเงื่อนไข (upsert) ได้ในคำสั่งเดียว
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.updateWithUpsertDemo.insertOne({"StudentFirstName":"John","StudentAge":21});
{ "acknowledged": true, "insertedId": ObjectId("5cd2a61c345990cee87fd890") }
> db.updateWithUpsertDemo.insertOne({"StudentFirstName":"Larry","StudentAge":23});
{ "acknowledged": true, "insertedId": ObjectId("5cd2a624345990cee87fd891") }
> db.updateWithUpsertDemo.insertOne({"StudentFirstName":"David","StudentAge":24});
{ "acknowledged": true, "insertedId": ObjectId("5cd2a62c345990cee87fd892") }
แสดงข้อมูลทั้งหมด
> db.updateWithUpsertDemo.find().pretty();
ผลลัพธ์:
{
"_id": ObjectId("5cd2a61c345990cee87fd890"),
"StudentFirstName": "John",
"StudentAge": 21
}
{
"_id": ObjectId("5cd2a624345990cee87fd891"),
"StudentFirstName": "Larry",
"StudentAge": 23
}
{
"_id": ObjectId("5cd2a62c345990cee87fd892"),
"StudentFirstName": "David",
"StudentAge": 24
}
คำสั่ง Upsert: อัปเดตหรือสร้างใหม่
เปลี่ยนชื่อ Larry เป็น Chris โดยใช้ _id เป็นเงื่อนไข:
> db.updateWithUpsertDemo.update(
{_id: ObjectId("5cd2a624345990cee87fd891")},
{"$set": {"StudentFirstName": "Chris"}},
{upsert: true}
);
WriteResult({ "nMatched": 1, "nUpserted": 0, "nModified": 1 })
ตรวจสอบผลลัพธ์
> db.updateWithUpsertDemo.find().pretty();
ชื่อเปลี่ยนจาก Larry เป็น Chris แล้ว:
{
"_id": ObjectId("5cd2a61c345990cee87fd890"),
"StudentFirstName": "John",
"StudentAge": 21
}
{
"_id": ObjectId("5cd2a624345990cee87fd891"),
"StudentFirstName": "Chris",
"StudentAge": 23
}
{
"_id": ObjectId("5cd2a62c345990cee87fd892"),
"StudentFirstName": "David",
"StudentAge": 24
}
สรุปการทำงานของ Upsert
- พบเอกสาร: อัปเดตตาม
$set(nMatched=1, nModified=1) - ไม่พบเอกสาร: สร้างเอกสารใหม่โดยรวมเงื่อนไข query และ update เข้าด้วยกัน (nUpserted=1)
- ต้องใช้
$setเพื่อไม่ให้แทนที่เอกสารทั้งหมด