Để 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: truetrongupdateOne/updateMany. bulkWriteatomic ở mức từng operation, không phải transaction toàn bộ batch (trừ khi dùng trong session transaction).