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

Cập nhật document cụ thể trong mảng với $set và positional $ operator

Cập nhật phần tử mảng chính xác với Positional $ Operator

Toán tử positional $ xác định vị trí phần tử khớp trong mảng để cập nhật chính xác phần tử đó.

1. Dữ liệu: mảng DueDateDetails

> db.demo462.insertOne({
    id: 1,
    DueDateDetails: [
        { Name: "David", Age: 21, CountryName: ["US", "UK"] },
        { Name: "Chris", Age: 23, CountryName: ["UK"] }
    ]
});
{ "acknowledged": true, "insertedId": ObjectId("5e7f6c59cb66ccba22cc9dce") }

2. Cập nhật CountryName của Chris thành "AUS"

> db.demo462.updateOne(
    { id: 1, "DueDateDetails.Name": "Chris" },
    { $set: { "DueDateDetails.$.CountryName": "AUS" } }
);
{ "acknowledged": true, "matchedCount": 1, "modifiedCount": 1 }

3. Kết quả

> db.demo462.find().pretty();
{
    "_id": ObjectId("5e7f6c59cb66ccba22cc9dce"),
    "id": 1,
    "DueDateDetails": [
        { "Name": "David", "Age": 21, "CountryName": ["US", "UK"] },
        { "Name": "Chris", "Age": 23, "CountryName": "AUS" }  // Đã thay đổi từ ["UK"] → "AUS"
    ]
}

Cơ chế Positional $ Operator

  • Filter "DueDateDetails.Name": "Chris" tìm thấy phần tử index 1
  • $ trong update tham chiếu đến chính phần tử index 1 đó
  • Chỉ cập nhật phần tử khớp, không ảnh hưởng phần tử khác

Các biến thể Positional Operator (MongoDB 3.6+)

$$[]$[]
OperatorTênÁp dụng cho
Positional (first match)Phần tử ĐẦU TIÊN khớp filter
All positionalTẤT CẢ phần tử trong mảng
Filtered positionalPhần tử khớp arrayFilters

Ví dụ $[] (cập nhật tất cả phần tử)

// Thêm "VN" vào CountryName của TẤT CẢ học sinh
db.demo462.updateOne(
    { id: 1 },
    { $push: { "DueDateDetails.$[].CountryName": "VN" } }
);

Ví dụ $[] (filtered positional)

// Chỉ cập nhật học sinh Age > 22
db.demo462.updateOne(
    { id: 1 },
    { $set: { "DueDateDetails.$[elem].Status": "Senior" } },
    { arrayFilters: [{ "elem.Age": { $gt: 22 } }] }
);

Lưu ý quan trọng

  • Positional $ chỉ hoạt động khi filter mảng ở cấp độ 1
  • Mảng lồng nhiều cấp (nested array) → dùng $[] với arrayFilters
  • Filter trong updateOne phải khớp document VÀ phần tử mảng