$lookup ทำ Left Outer Join ระหว่างคอลเลกชัน โดยระบุ from (คอลเลกชันปลายทาง), localField/foreignField หรือใช้ pipeline สำหรับเงื่อนไขซับซ้อน เช่น Join กับอาร์เรย์ ObjectId
คอลเลกชันแรก: demo395 (ข้อมูลหลัก)
> db.demo395.insertOne({Name:"Chris"});
> db.demo395.insertOne({Name:"David"});
{
"_id" : ObjectId("5e5e782317aa3ef9ab8ab207"), "Name" : "Chris"
}
{
"_id" : ObjectId("5e5e782317aa3ef9ab8ab208"), "Name" : "David"
}
คอลเลกชันที่สอง: demo396 (มีอาร์เรย์ ObjectId อ้างอิง demo395)
> db.demo396.insertOne({
"details" : [
ObjectId("5e5e782317aa3ef9ab8ab207"),
ObjectId("5e5e782317aa3ef9ab8ab208")
]
});
{
"_id" : ObjectId("5e5e787817aa3ef9ab8ab209"),
"details" : [
ObjectId("5e5e782317aa3ef9ab8ab207"),
ObjectId("5e5e782317aa3ef9ab8ab208")
]
}
คำสั่ง $lookup ด้วย Pipeline (Uncorrelated Subquery)
> db.demo396.aggregate([
{"$lookup": {
"from": "demo395",
"let": {"details": "$details"},
"pipeline": [
{"$match": {"$expr": {"$in": ["$_id", "$$details"]}}}
],
"as": "output"
}}
])
ผลลัพธ์ (รวมข้อมูลจาก demo395 เข้ามาใน output)
{
"_id" : ObjectId("5e5e787817aa3ef9ab8ab209"),
"details" : [
ObjectId("5e5e782317aa3ef9ab8ab207"),
ObjectId("5e5e782317aa3ef9ab8ab208")
],
"output" : [
{"_id" : ObjectId("5e5e782317aa3ef9ab8ab207"), "Name" : "Chris"},
{"_id" : ObjectId("5e5e782317aa3ef9ab8ab208"), "Name" : "David"}
]
}
คำอธิบาย:
letส่งตัวแปร details (อาร์เรย์ ObjectId) เข้า pipelinepipelineใช้$match+$expr+$inค้นหา _id ที่อยู่ใน $$detailsas: "output"เก็บผลลัพธ์เป็นอาร์เรย์ในฟิลด์ output
วิธีนี้ยืดหยุ่นกว่า localField/foreignField เพราะรองรับอาร์เรย์และเงื่อนไขซับซ้อน