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

Truy vấn aggregate mảng lồng nhau trong MongoDB

Aggregation mảng lồng nhiều cấp (nested array)

Xử lý mảng lồng sâu với $map, $let, $arrayElemAt, $cond để trích xuất và biến đổi dữ liệu.

1. Dữ liệu phức tạp: mảng details → mảng details1

> db.demo441.insertOne({
    Name: "David", Age: 21,
    details: [{
        id: 1, CountryName: "US",
        details1: [
            { SubjectName: "MySQL", Score: 56 },
            { SubjectName: "MongoDB", Score: 78 }
        ]
    }]
});
{ "acknowledged": true, "insertedId": ObjectId("5e78cc05bbc41e36cc3caeb7") }

2. Pipeline aggregation

> db.demo441.aggregate([{
    $addFields: {
        ResultOfDetails: {
            $map: {
                input: "$details",
                as: "output",
                in: {
                    id: "$$output.id",
                    CountryName: "$$output.CountryName",
                    details1: {
                        $let: {
                            vars: {
                                last: { $arrayElemAt: ["$$output.details1", -1] }
                            },
                            in: {
                                $cond: [
                                    { $eq: ["$$last.Score", 78] },
                                    ["$$last"],
                                    []
                                ]
                            }
                        }
                    }
                }
            }
        }
    }
}]).pretty();

3. Kết quả

{
    "_id": ObjectId("5e78cc05bbc41e36cc3caeb7"),
    "Name": "David", "Age": 21,
    "details": [{ "id": 1, "CountryName": "US", "details1": [{ "SubjectName": "MySQL", "Score": 56 }, { "SubjectName": "MongoDB", "Score": 78 }] }],
    "ResultOfDetails": [{
        "id": 1, "CountryName": "US",
        "details1": [{ "SubjectName": "MongoDB", "Score": 78 }]
    }]
}

Giải thích các toán tử chính

Toán tửChức năng
$mapDuyệt mảng, biến đổi từng phần tử
$letĐịnh nghĩa biến cục bộ (vars) để tái sử dụng
$arrayElemAtLấy phần tử tại index (index âm = từ cuối)
$condIf-then-else: điều kiện, true-case, false-case

Logic ví dụ này

  1. Duyệt qua mảng details
  2. Với mỗi item, lấy phần tử cuối cùng của details1 (index -1)
  3. Nếu Score == 78 → giữ phần tử đó, ngược lại → mảng rỗng
  4. Tạo trường mới ResultOfDetails chứa kết quả biến đổi

Mẹo: Với mảng lồng sâu, hãy phân tích từng cấp độ và dùng $unwind nếu cần flatten trước khi xử lý.