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

Trả về tài liệu với sub-document đã lọc trong MongoDB

Lọc sub-document trong mảng với $project + $filter

Sử dụng $filter trong stage $project của aggregation để chỉ giữ các phần tử mảng thỏa mãn điều kiện, thay vì trả về toàn bộ mảng.

1. Dữ liệu: mảng details chứa sản phẩm

> db.demo457.insertOne({
    _id: 101,
    details: [
        { ProductName: "Product-1", ProductPrice: 90 },
        { ProductName: "Product-2", ProductPrice: 190 }
    ]
});
> db.demo457.insertOne({
    _id: 102,
    details: [
        { ProductName: "Product-3", ProductPrice: 150 },
        { ProductName: "Product-4", ProductPrice: 360 }
    ]
});

2. Pipeline: Chỉ giữ sản phẩm giá >= 170

> db.demo457.aggregate([
    {
        $project: {
            details: {
                $filter: {
                    input: "$details",
                    as: "output",
                    cond: { $gte: ["$$output.ProductPrice", 170] }
                }
            }
        }
    }
]);

3. Kết quả

{ "_id": 101, "details": [{ "ProductName": "Product-2", "ProductPrice": 190 }] }
{ "_id": 102, "details": [{ "ProductName": "Product-4", "ProductPrice": 360 }] }

Cú pháp $filter

{
    $filter: {
        input: ,           // Mảng nguồn
        as: ,             // Biến đại diện cho phần tử (vd: "output")
        cond:         // Điều kiện boolean, dùng $$output.trường
    }
}

So sánh: $filter vs $unwind + $match

CáchƯu điểmNhược điểm
$filterGiữ cấu trúc doc, 1 stage, nhanhKhông tạo doc mới cho mỗi phần tử
$unwind + $matchCó thể dùng $group sau, linh hoạtTạo nhiều doc trung gian, chậm hơn

Mở rộng: Lọc và biến đổi (map + filter)

{
    $project: {
        expensiveProducts: {
            $map: {
                input: {
                    $filter: {
                        input: "$details",
                        as: "p",
                        cond: { $gte: ["$$p.ProductPrice", 170] }
                    }
                },
                as: "item",
                in: { name: "$$item.ProductName", price: "$$item.ProductPrice", discount: { $multiply: ["$$item.ProductPrice", 0.9] } }
            }
        }
    }
}

Kết quả: Mảng chỉ chứa sản phẩm đắt, kèm giá giảm 10%.