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

Loại trừ trường lồng nhau (nested fields) bằng wildcard trong MongoDB

MongoDB **không hỗ trợ wildcard** (như details.*.Age) trực tiếp trong projection của find(). Để loại trừ trường lồng nhau động (không biết tên key cha), bạn dùng **Aggregation Pipeline** với $objectToArray -> lọc -> $arrayToObject.

1. Tạo dữ liệu: Object details có key động Info1, Info2 (mỗi key chứa object Name, Age)

> db.demo413.insertOne({
    "_id": "101",
    "details": {
        "Info1": { "Name": "Chris", "Age": 21 },
        "Info2": { "Name": "David", "Age": 23 }
    }
});

2. Xem dữ liệu

> db.demo413.find();

Kết quả: details.Info1, Info2 đều có Name, Age.

3. Aggregation: Loại bỏ trường Age khỏi TẤT CẢ sub-object trong details

> db.demo413.aggregate([
    // B1: Chuyển object details -> mảng [{k: "Info1", v: {Name, Age}}, {k: "Info2", v: {Name, Age}}]
    { $project: { "details": { $objectToArray: "$details" } } },

    // B2: Loại bỏ trường "Age" trong mỗi phần tử v (value) của mảng
    { $project: { "details.v.Age": 0 } },

    // B3: Chuyển mảng k/v ngược lại thành object
    { $project: { "details": { $arrayToObject: "$details" } } }
]);

4. Kết quả

{ "_id": "101", "details": { "Info1": { "Name": "Chris" }, "Info2": { "Name": "David" } } }

Giải thích quy trình:

  1. $objectToArray: Biến object lồng thành mảng cặp key-value (k, v).
  2. Projection { "details.v.Age": 0 }: Loại bỏ Age trong value (v) của mỗi phần tử mảng details.
  3. $arrayToObject: Ghép mảng k/v ngược thành object.

Cách khác (MongoDB 4.2+): Dùng $set / $unset trong update với $[] (all positional) nếu muốn **cập nhật vĩnh viễn** vào DB:

db.demo413.updateMany({}, { $unset: { "details.$[].Age": "" } });

Cách này đơn giản hơn nhiều cho việc sửa dữ liệu thực tế.