Sử dụng $facet để xử lý nhiều pipeline song song
Toán tử $facet cho phép chạy nhiều pipeline aggregation độc lập trên cùng một tập dữ liệu đầu vào, rất hữu ích khi cần đếm theo nhiều trường khác nhau.
Dữ liệu mẫu
> db.demo721.insertMany([
{ details1: { id: 101 }, details2: { id: 101 }, details3: { id: 101 } },
{ details1: { id: 101 }, details2: { id: 102 }, details3: { id: 102 } }
]);
Truy vấn phức tạp với $facet
db.demo721.aggregate([
{
$facet: {
ids: [
{
$group: {
_id: null,
d3: { $addToSet: "$details3.id" },
d2: { $addToSet: "$details2.id" },
d1: { $addToSet: "$details1.id" }
}
},
{
$project: {
_id: 0,
listofall: { $setUnion: ["$d1", "$d2", "$d3"] }
}
}
],
d: [
{ $project: { _id: 0, a1: "$details1.id", a2: "$details2.id", a3: "$details3.id" } }
]
}
},
{ $unwind: "$d" },
{ $unwind: "$ids" },
{ $unwind: "$ids.listofall" },
{
$group: {
_id: "$ids.listofall",
details1id: { $sum: { $cond: [{ $eq: ["$d.a1", "$ids.listofall"] }, 1, 0] } },
details2id: { $sum: { $cond: [{ $eq: ["$d.a2", "$ids.listofall"] }, 1, 0] } },
details3id: { $sum: { $cond: [{ $eq: ["$d.a3", "$ids.listofall"] }, 1, 0] } }
}
}
]);
Kết quả
{ "_id": 102, "details1id": 0, "details2id": 1, "details3id": 1 }
{ "_id": 101, "details1id": 2, "details2id": 1, "details3id": 1 }
Kết quả cho thấy số lần xuất hiện của mỗi ID trong ba trường details1, details2, details3.