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

Gộp nhiều mảng thành một mảng lớn trong MongoDB

Để gộp nhiều mảng thành một và lọc phần tử, dùng $setUnion, $ifNull, $filter trong stage $project của aggregate.

Dữ liệu mẫu

> db.demo119.insertOne({
    "_id": 101,
    "WebDetails": [ 
        { "ImagePath": "/all/image1", "isCorrect": "false" }, 
        { "ImagePath": "/all/image2", "isCorrect": "true" } 
    ],
    "ClientDetails": [ 
        { "Name": "Chris", "isCorrect": "false" }, 
        { "Name": "David", "isCorrect": "true" } 
    ]
});
{ "acknowledged" : true, "insertedId" : 101 }

Pipeline aggregate

> db.demo119.aggregate([
    { "$project": { 
        "AllDetails": { 
            "$filter": { 
                "input": { 
                    "$setUnion": [ 
                        { "$ifNull": [ "$WebDetails", [] ] }, 
                        { "$ifNull": [ "$ClientDetails", [] ] } 
                    ] 
                }, 
                "as": "out", 
                "cond": { "$eq": [ "$$out.isCorrect", "false" ] } 
            } 
        } 
    }},
    { "$match": { "AllDetails.0": { "$exists": true } } }
]);

Kết quả

{ "_id" : 101, "AllDetails" : [ { "ImagePath" : "/all/image1", "isCorrect" : "false" }, { "Name" : "Chris", "isCorrect" : "false" } ] }

Giải thích:

  • $ifNull: Xử lý trường hợp mảng null/không tồn tại → trả về mảng rỗng
  • $setUnion: Gộp 2 mảng, loại bỏ phần tử trùng lặp (so sánh toàn bộ object)
  • $filter: Lọc phần tử có isCorrect="false"
  • $match: Chỉ giữ document có AllDetails không rỗng

Lưu ý: $setUnion so sánh toàn bộ object. Nếu cấu trúc khác nhau (ImagePath vs Name), không bị coi là trùng. Dùng $concatArrays nếu muốn giữ trùng lặp và thứ tự.