Aggregate hai collection với điều kiện so sánh trường ($lookup + $redact)
Sử dụng $lookup để join 2 collection, sau đó $redact để lọc dựa trên so sánh giá trị giữa hai collection.
1. Collection demo446 (giá cao hơn)
> db.demo446.insert([
{ "ProductName": "Product1", "ProductPrice": 60 },
{ "ProductName": "Product2", "ProductPrice": 90 }
]);
2. Collection demo447 (giá thấp hơn)
> db.demo447.insert([
{ "ProductName": "Product1", "ProductPrice": 40 },
{ "ProductName": "Product2", "ProductPrice": 70 }
]);
3. Pipeline aggregation phức tạp
> var rate = 1;
> db.demo446.aggregate([
{ $match: { ProductPrice: { $exists: true }, ProductName: { $exists: true } } },
{
$lookup: {
from: "demo447",
localField: "ProductName",
foreignField: "ProductName",
as: "demo447"
}
},
{ $unwind: "$demo447" },
{
$redact: {
$cond: [
{
$gt: [
"$ProductPrice",
{ $add: [{ $multiply: ["$demo447.ProductPrice", rate] }, 3] }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
4. Kết quả
{
"_id": ObjectId("5e790766bbc41e36cc3caec3"),
"ProductName": "Product1",
"ProductPrice": 60,
"demo447": { "_id": ObjectId("5e790789bbc41e36cc3caec5"), "ProductName": "Product1", "ProductPrice": 40 }
}
{
"_id": ObjectId("5e790766bbc41e36cc3caec4"),
"ProductName": "Product2",
"ProductPrice": 90,
"demo447": { "_id": ObjectId("5e790789bbc41e36cc3caec6"), "ProductName": "Product2", "ProductPrice": 70 }
}
Giải thích điều kiện
Giữ tài liệu khi: ProductPrice (demo446) > ProductPrice (demo447) * rate + 3
- Product1: 60 > 40*1 + 3 = 43 → Giữ
- Product2: 90 > 70*1 + 3 = 73 → Giữ
Lưu ý hiệu suất
$redactxử lý sau $unwind, có thể chậm với dữ liệu lớn- Cân nhắc dùng
$matchsau $unwind thay vì $redact cho truy vấn đơn giản - Đảm bảo có index trên
ProductNameở cả 2 collection