Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Upsert có điều kiện (Conditional Upsert) nhiều tài liệu trong MongoDB với bulkWrite

Để thực hiện nhiều thao tác ghi (insert/update/upsert) khác nhau trong một lần gọi mạng (round-trip), MongoDB cung cấp bulkWrite(). Điều này hiệu quả hơn nhiều so với chạy nhiều lệnh riêng lẻ. Bài toán: Cập nhật David (Age 22) thêm Info, và chèn mới Carol (Age 22) với Info giống nhau - cả hai trong một bulk.

1. Tạo dữ liệu ban đầu

> db.demo428.insertOne({ "Name": "Chris", "Age": 21 });
> db.demo428.insertOne({ "Name": "Chris", "Age": 23 });
> db.demo428.insertOne({ "Name": "David", "Age": 22 });
> db.demo428.insertOne({ "Name": "David", "Age": 21 });

2. bulkWrite: 1 updateOne (có upsert:false mặc định) + 1 insertOne

> db.demo428.bulkWrite([
    {
        updateOne: {
            filter: { "Name": "David", "Age": 22 },
            update: { $set: { "Info": { Name: "John" } } }
            // upsert: false (mặc định) -> chỉ update nếu tìm thấy
        }
    },
    {
        insertOne: {
            document: { "Name": "Carol", "Age": 22, "Info": { Name: "John" } }
        }
    }
], { ordered: false }); // false = tiếp tục dù có lỗi (unordered)

3. Kết quả

{
    "acknowledged": true,
    "insertedCount": 1,      // Carol inserted
    "matchedCount": 1,       // David matched
    "modifiedCount": 1,      // David updated
    "upsertedCount": 0,
    "insertedIds": { "1": ObjectId("5e75f448bbc41e36cc3cae87") }
}

4. Dữ liệu sau bulkWrite

> db.demo428.find();

Kết quả: 5 tài liệu. David (Age 22) có thêm Info. Carol mới được insert.

Giải thích:

  • ordered: false: Unordered bulk - song song, nhanh hơn, không dừng khi lỗi.
  • ordered: true (mặc định): Sequential - dừng tại lỗi đầu tiên.
  • Để upsert trong bulk: Thêm upsert: true trong updateOne/updateMany.
  • bulkWrite atomic ở mức từng operation, không phải transaction toàn bộ batch (trừ khi dùng trong session transaction).