Cập nhật phần tử trong mảng object với positional $ operator
Sử dụng update() với filter trên trường trong mảng object, kết hợp positional $ để cập nhật chính xác phần tử khớp.
1. Dữ liệu: mảng tags chứa object {id, Name}
> db.demo713.insertOne({
tags: [
{ id: 101, Name: "Tag-1" },
{ id: 102, Name: "Tag-3" },
{ id: 103, Name: "Tag-3" }
]
});
{ "acknowledged": true, "insertedId": ObjectId("5ea8625a5d33e20ed1097b87") }
2. Cập nhật tag id=102: Name "Tag-3" → "Tag-2"
> db.demo713.update(
{ "tags.id": 102 },
{ $set: { "tags.$.Name": "Tag-2" } },
false, // upsert
true // multi
);
WriteResult({ "nMatched": 1, "nUpserted": 0, "nModified": 1 })
3. Kết quả
> db.demo713.find().pretty();
{
"_id": ObjectId("5ea8625a5d33e20ed1097b87"),
"tags": [
{ "id": 101, "Name": "Tag-1" },
{ "id": 102, "Name": "Tag-2" }, // Đã cập nhật
{ "id": 103, "Name": "Tag-3" }
]
}
Giải thích tham số update() cũ
db.collection.update(
, // { "tags.id": 102 }
, // { $set: { "tags.$.Name": "Tag-2" } }
, // false: không insert mới nếu không tìm thấy
// true: cập nhật TẤT CẢ doc khớp (mặc định false = 1 doc)
);
Phiên bản hiện đại (MongoDB 3.2+)
// Cập nhật 1 document (tương đương multi: false)
db.demo713.updateOne(
{ "tags.id": 102 },
{ $set: { "tags.$.Name": "Tag-2" } }
);
// Cập nhật TẤT CẢ document (tương đương multi: true)
db.demo713.updateMany(
{ "tags.id": 102 },
{ $set: { "tags.$.Name": "Tag-2" } }
);
Lưu ý về positional $
- Chỉ cập nhật phần tử đầu tiên khớp filter trong mảng
- Nếu có 2 tag id=102 → chỉ cập nhật cái đầu tiên
- Muốn cập nhật tất cả phần tử khớp → dùng
$[]hoặc$[identifier](MongoDB 3.6+)
Ví dụ cập nhật TẤT CẢ tag có Name="Tag-3" thành "Tag-2"
db.demo713.updateMany(
{ "tags.Name": "Tag-3" },
{ $set: { "tags.$[elem].Name": "Tag-2" } },
{ arrayFilters: [{ "elem.Name": "Tag-3" }] }
);