Khi cần cập nhật phần tử mảng tại vị trí chỉ số được lưu trong biến (dynamic index), MongoDB yêu cầu xây dựng đối tượng cập nhật động vì không thể sử dụng biến trực tiếp trong cú pháp dot notation tĩnh.
Cú pháp kỹ thuật
var yourIndexVariableName = yourIndexValue,
anyVariableName = { "$set": {} };
anyVariableName["$set"]["yourFieldName." + yourIndexVariableName] = "yourValue";
db.yourCollectionName.update({ "_id": yourObjectId }, anyVariableName);
Tạo dữ liệu mẫu
> db.updateByVariableDemo.insertOne({"StudentSubjects":["MySQL","Java","SQL Server","PL/SQL"]});
{ "acknowledged" : true, "insertedId" : ObjectId("5cd553c37924bb85b3f4893a") }
Xem dữ liệu ban đầu
> db.updateByVariableDemo.find().pretty();
Cập nhật theo chỉ số biến
Thay đổi phần tử tại chỉ số 1 (Java) thành "MongoDB":
> var indexValue = 1, valueToUpdate = { "$set": {} }; > valueToUpdate["$set"]["StudentSubjects." + indexValue] = "MongoDB"; MongoDB > db.updateByVariableDemo.update({ "_id": ObjectId("5cd553c37924bb85b3f4893a") }, valueToUpdate); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })Kết quả
> db.updateByVariableDemo.find().pretty();Giải thích kỹ thuật
- Khởi tạo biến
indexValue = 1(chỉ số cần cập nhật)- Tạo đối tượng cập nhật rỗng:
valueToUpdate = {"$set": {}}- Gán động key:
valueToUpdate["$set"]["StudentSubjects." + indexValue] = "MongoDB"- Kết quả:
{"$set": {"StudentSubjects.1": "MongoDB"}}- Thực thi
update()với đối tượng động nàyCách hiện đại hơn (MongoDB 3.6+)
Sử dụng
arrayFiltersvới$[<identifier>]:var indexValue = 1; db.updateByVariableDemo.updateOne( {_id: ObjectId("5cd553c37924bb85b3f4893a")}, {$set: {"StudentSubjects.$[elem]": "MongoDB"}}, {arrayFilters: [{"elem": {$eq: "$$StudentSubjects." + indexValue}}]} // Cần điều chỉnh logic );Lưu ý: arrayFilters phù hợp hơn cho điều kiện giá trị, không phải chỉ số thuần túy.
Ứng dụng thực tế
- Cập nhật điểm số sinh viên tại vị trí môn học cụ thể
- Thay đổi trạng thái task trong mảng theo index từ frontend
- Xử lý form động gửi lên chỉ số mảng cần sửa
Lưu ý
- Chỉ số mảng bắt đầu từ 0
- Nếu chỉ số vượt quá độ dài mảng, MongoDB sẽ không báo lỗi mà không cập nhật gì
- Luôn validate chỉ số ở application layer trước khi gửi truy vấn