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

MongoDB สามารถคืนค่าผลลัพธ์หลัง Increment ได้หรือไม่? (findAndModify)

ใช่ สามารถทำได้โดยใช้ findAndModify() ซึ่งทำการ Find, Modify, และ Return เอกสารที่อัปเดตแล้วใน Atomic Operation เดียว

สร้างคอลเลกชันและข้อมูลตัวอย่าง

> db.returnResultOfIncementDemo.insertOne({"PlayerScore": 98});
{ "acknowledged": true, "insertedId": ObjectId("5cd3c292edc6604c74817cda") }

แสดงข้อมูลก่อน

> db.returnResultOfIncementDemo.find();

ผลลัพธ์:

{"_id": ObjectId("5cd3c292edc6604c74817cda"), "PlayerScore": 98}

คำสั่ง: Increment และคืนค่าเอกสารใหม่ (new: true)

> db.returnResultOfIncementDemo.findAndModify({
  query: {},
  update: {$inc: {PlayerScore: 2}},
  new: true
});

ผลลัพธ์: คืนเอกสารหลังอัปเดต (PlayerScore = 100)

{"_id": ObjectId("5cd3c292edc6604c74817cda"), "PlayerScore": 100}

พารามิเตอร์สำคัญของ findAndModify

พารามิเตอร์คำอธิบายค่า Default
queryเงื่อนไขค้นหาเอกสาร{}
updateUpdate Operators ($inc, $set, etc.)Required
newtrue = คืนเอกสารหลังอัปเดต, false = คืนเอกสารก่อนอัปเดตfalse
upserttrue = สร้างใหม่หากไม่พบfalse
sortเรียงลำดับหากมีหลายเอกสารตรง Query-
fieldsProjection (เลือกฟิลด์ที่คืน)-

รูปแบบใหม่ (MongoDB 3.2+): findOneAndUpdate

// แทน findAndModify (Deprecated ใน Shell)
db.returnResultOfIncementDemo.findOneAndUpdate(
  {},
  {$inc: {PlayerScore: 2}},
  {returnDocument: "after"}  // "after" = new: true, "before" = new: false
);

กรณีใช้งานจริง (Use Cases)

  • Counter/Sequence Generator: ดึงหมายเลขถัดไป Atomic
  • Queue/Job Processing: Claim Job และ Update Status พร้อมกัน
  • Inventory: ลด Stock และเช็คคงเหลือในครั้งเดียว
  • Rate Limiting: นับ Request และ Block ถ้าเกิน

ตัวอย่าง Counter แบบ Atomic

function getNextSequence(name) {
  var ret = db.counters.findAndModify(
    {_id: name},
    [],
    {$inc: {seq: 1}},
    {new: true, upsert: true}
  );
  return ret.seq;
}

// ใช้งาน
getNextSequence("orderId"); // 1
getNextSequence("orderId"); // 2