Để tìm kiếm và cập nhật một phần tử cụ thể bên trong mảng (subdocument) dựa trên trường _id của phần tử đó, MongoDB cung cấp Positional Operator $. Toán tử này xác định vị trí phần tử khớp điều kiện trong mảng và cho phép cập nhật chính xác phần tử đó.
1. Tạo bộ sưu tập và chèn dữ liệu
> db.demo49.insertOne({
"Name": "David",
"Details": [
{ "_id": "D1234", "Subject": "MySQL" },
{ "_id": "E234", "Subject": "Java" },
{ "_id": "F456", "Subject": "Python" }
]
});
{ "acknowledged": true, "insertedId": ObjectId("5e270a77cfb11e5c34d89902") }
2. Xem dữ liệu ban đầu
> db.demo49.find();
Kết quả:
{ "_id": ObjectId("..."), "Name": "David", "Details": [
{ "_id": "D1234", "Subject": "MySQL" },
{ "_id": "E234", "Subject": "Java" },
{ "_id": "F456", "Subject": "Python" }
] }
3. Cập nhật Subject của phần tử có _id = 'E234' thành 'MongoDB'
> db.demo49.update(
{ "Details._id": "E234" },
{ $set: { "Details.$.Subject": "MongoDB" } }
);
WriteResult({ "nMatched": 1, "nUpserted": 0, "nModified": 1 })
Giải thích:
- Điều kiện
{ "Details._id": "E234" }tìm tài liệu chứa phần tử này. $setvớiDetails.$.Subject: dấu$tham chiếu đến phần tử đầu tiên khớp trong mảngDetails.
4. Kết quả sau cập nhật
> db.demo49.find();
Kết quả:
{ "_id": ObjectId("..."), "Name": "David", "Details": [
{ "_id": "D1234", "Subject": "MySQL" },
{ "_id": "E234", "Subject": "MongoDB" },
{ "_id": "F456", "Subject": "Python" }
] }
Lưu ý: Nếu cần cập nhật tất cả phần tử khớp trong mảng, dùng $[] (all positional operator) thay vì $ (MongoDB 3.6+).