Để cập nhật một trường bên trong object nằm trong mảng, dựa trên giá trị của **trường khác trong cùng object đó**, MongoDB dùng **Positional Operator $**. Toán tử `$` xác định vị trí (index) của phần tử khớp điều kiện trong mảng.
1. Tạo bộ sưu tập sản phẩm
> db.demo419.insertOne({
"ProductInformation": [
{ "ProductName": "Product-1", "ProductPrice": 500 },
{ "ProductName": "Product-2", "ProductPrice": 600 }
]
});
{ "acknowledged": true, "insertedId": ObjectId("5e724762b912067e57771ae8") }
2. Xem dữ liệu
> db.demo419.find();
Kết quả: Mảng 2 sản phẩm.
3. Cập nhật giá Product-1 từ 500 -> 1250
> db.demo419.update(
{ 'ProductInformation.ProductName': "Product-1" },
{ $set: { 'ProductInformation.$.ProductPrice': 1250 } }
);
WriteResult({ "nMatched": 1, "nUpserted": 0, "nModified": 1 })
Giải thích:
- Filter:
{ 'ProductInformation.ProductName': "Product-1" }tìm tài liệu chứa sản phẩm này. - Update:
$setvớiProductInformation.$.ProductPrice-> dấu `$` thay cho index của phần tử khớp (index 0).
4. Kết quả
> db.demo419.find();
Kết quả:
{ "_id": ObjectId("..."), "ProductInformation": [
{ "ProductName": "Product-1", "ProductPrice": 1250 },
{ "ProductName": "Product-2", "ProductPrice": 600 }
] }
Lưu ý quan trọng:
$chỉ cập nhật **phần tử đầu tiên** khớp điều kiện trong mảng.- Cần cập nhật **tất cả** phần tử khớp? Dùng
$[](All positional operator, MongoDB 3.6+):{ $set: { 'ProductInformation.$[].ProductPrice': 1250 } }. - Cần cập nhật theo nhiều điều kiện? Dùng
$[với] arrayFilters(MongoDB 3.6+).