Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Cách dùng $set cập nhật giá trị lồng nhau (nested/embedded) trong MongoDB

Để cập nhật giá trị của trường lồng nhau (nested field / embedded document) trong MongoDB, bạn sử dụng toán tử $set với dot notation (ký pháp dấu chấm).

Cú pháp

db.collection.update(
    { query },
    { $set: { "outerField.innerField": "newValue" } }
)

Ví dụ minh họa

Tạo collection và dữ liệu

> db.updateNestedValueDemo.insertOne({
    "CustomerName": "Chris",
    "CustomerDetails": {
        "CustomerAge": 25,
        "CustomerCompanyName": "Google",
        "CustomerCityName": "US"
    }
});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8fccc4d3c9d04998abf015") }

Xem dữ liệu ban đầu

> db.updateNestedValueDemo.find().pretty();
{
    "_id" : ObjectId("5c8fccc4d3c9d04998abf015"),
    "CustomerName" : "Chris",
    "CustomerDetails" : {
        "CustomerAge" : 25,
        "CustomerCompanyName" : "Google",
        "CustomerCityName" : "US"
    }
}

Cập nhật trường lồng nhau: CustomerCompanyName từ "Google" → "Dell"

> db.updateNestedValueDemo.update(
    { }, 
    { $set: { "CustomerDetails.CustomerCompanyName": "Dell" } }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Kiểm tra kết quả

> db.updateNestedValueDemo.find().pretty();
{
    "_id" : ObjectId("5c8fccc4d3c9d04998abf015"),
    "CustomerName" : "Chris",
    "CustomerDetails" : {
        "CustomerAge" : 25,
        "CustomerCompanyName" : "Dell",
        "CustomerCityName" : "US"
    }
}

Trường CustomerDetails.CustomerCompanyName đã được cập nhật từ "Google" thành "Dell", các trường khác giữ nguyên.

Dot Notation - Ký pháp dấu chấm

MongoDB dùng dấu chấm . để truy cập trường lồng nhau:

  • "outer.inner" - 1 cấp lồng
  • "outer.middle.inner" - 2 cấp lồng
  • "array.0.field" - truy cập phần tử mảng index 0

Các ví dụ nâng cao

Cập nhật nhiều trường lồng nhau cùng lúc

db.updateNestedValueDemo.update(
    { "CustomerName": "Chris" },
    { 
        $set: { 
            "CustomerDetails.CustomerCompanyName": "Microsoft",
            "CustomerDetails.CustomerCityName": "Seattle",
            "CustomerDetails.CustomerAge": 26
        } 
    }
);

Cập nhật phần tử trong mảng lồng nhau

// Giả sử CustomerDetails.Projects là mảng
db.coll.update(
    { _id: ObjectId("...") },
    { $set: { "CustomerDetails.Projects.0.status": "completed" } }
);

Cập nhật có điều kiện (arrayFilters - MongoDB 3.6+)

db.students.updateMany(
    { "grades.course": "math" },
    { $set: { "grades.$[elem].passed": true } },
    { arrayFilters: [{ "elem.score": { $gte: 60 } }] }
);

Lưu ý

  • Luôn dùng $set để cập nhật một phần document, không replace toàn bộ
  • Nếu đường dẫn không tồn tại, MongoDB sẽ tạo mới (upsert behavior)
  • Tên trường có dấu chấm hoặc ký tự đặc biệt → dùng bracket notation trong code driver, nhưng trong shell dùng string "field.name" vẫn OK
  • Kết hợp với upsert: true để tạo document nếu không tồn tại