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

Truy vấn MongoDB cập nhật tag trong mảng

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" }] }
);