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

Cập nhật object trong mảng tại index N MongoDB

Cập nhật phần tử mảng object tại vị trí cụ thể với dot notation

Kết hợp filter trên trường trong mảng object với positional $ operator để cập nhật chính xác phần tử khớp.

1. Dữ liệu: mảng details chứa object Info1, Info2

> db.demo489.insertOne({
    details: [
        { id: 101, Info1: { StudentName: "Chris" }, Info2: { TeacherName: "David" } },
        { id: 102, Info1: { StudentName: "Carol" }, Info2: { TeacherName: "Mike" } }
    ]
});

2. Cập nhật phần tử có id=102

> db.demo489.update(
    { "details.id": 102 },
    {
        $set: {
            "details.$.Info1.StudentName": "Robert",
            "details.$.Info2.TeacherName": "John",
            "details.$.CountryName": "US"
        }
    }
);
WriteResult({ "nMatched": 1, "nUpserted": 0, "nModified": 1 })

3. Kết quả

> db.demo489.find().pretty();
{
    "_id": ObjectId("5e8356e0b0f3fa88e22790ba"),
    "details": [
        { "id": 101, "Info1": { "StudentName": "Chris" }, "Info2": { "TeacherName": "David" } },
        { "id": 102, "Info1": { "StudentName": "Robert" }, "Info2": { "TeacherName": "John" }, "CountryName": "US" }
    ]
}

Giải thích

  • Filter { "details.id": 102 } tìm document VÀ xác định index mảng (index 1)
  • $ trong update tham chiếu đến phần tử index 1
  • Cập nhật lồng: details.$.Info1.StudentName → truy cập sâu 3 cấp
  • Thêm trường mới: details.$.CountryName tạo mới trong object phần tử đó

Phiên bản hiện đại (MongoDB 3.2+)

db.demo489.updateOne(
    { "details.id": 102 },
    {
        $set: {
            "details.$.Info1.StudentName": "Robert",
            "details.$.Info2.TeacherName": "John",
            "details.$.CountryName": "US"
        }
    }
);

Cập nhật theo index vị trí (biết trước index)

// Cập nhật phần tử index 0 (phần tử đầu)
db.demo489.updateOne(
    { _id: docId },
    { $set: { "details.0.Info1.StudentName": "New Name" } }
);

// Cập nhật phần tử index 2 (phần tử thứ 3)
db.demo489.updateOne(
    { _id: docId },
    { $set: { "details.2.Info1.StudentName": "New Name" } }
);

Lưu ý quan trọng

  • Positional $ chỉ cập nhật phần tử ĐẦU TIÊN khớp
  • Nếu 2 phần tử có id=102 → chỉ cập nhật cái đầu tiên
  • Cần cập nhật tất cả → dùng $[] (all) hoặc $[id] với arrayFilters (MongoDB 3.6+)
  • Filter phải khớp document VÀ phần tử mảng

Ví dụ arrayFilters (MongoDB 3.6+) - Cập nhật TẤT CẢ id=102

db.demo489.updateMany(
    { },
    { $set: { "details.$[elem].Info1.StudentName": "Robert" } },
    { arrayFilters: [{ "elem.id": 102 }] }
);