NoSQL Databases • المستوى الثالث • الدرس 3
العودة لفهرس المستوىربط المجموعات بـ ($lookup)
أهداف الدرس
- دمج البيانات المرجعية من عدة مجموعات باستخدام
$lookup(Left Outer Join). - تحديد أسماء حقول الربط المتقابلة بين المجموعات.
- دمج
$lookupمع$unwindلتفكيك المصفوفة الناتجة. - دمج
$lookupمع$matchو$projectلتقارير متقدمة.
1. ما هو $lookup؟
$lookup هو بديل MongoDB عن JOIN في SQL. يدمج مستندات من مجموعة أخرى بناءً على حقل مشترك.
javascript
db.orders.aggregate([
{
$lookup: {
from: "users", // المجموعة الهدف
localField: "user_id", // حقل محلي في orders
foreignField: "_id", // حقل مقابل في users
as: "userDetails" // اسم الحقل الناتج
}
}
]);
// خط الأنابيب:
// [orders] -> $lookup -> [orders + userDetails[]]SQL JOIN
SELECT * FROM orders LEFT JOIN users ON orders.user_id = users._id
MongoDB $lookup
db.orders.aggregate([
{ $lookup: {
from: "users",
localField: "user_id",
foreignField: "_id",
as: "userDetails"
} }
])2. مكونات $lookup الأربعة
from
اسم المجموعة التي نريد الربط معها.
from: "users"
localField
الحقل في المجموعة الحالية.
localField: "user_id"
foreignField
الحقل المقابل في المجموعة الهدف.
foreignField: "_id"
as
اسم الحقل الجديد الذي يحمل النتائج.
as: "userDetails"
3. النتيجة دائماً مصفوفة — لماذا؟
$lookup يُرجع مصفوفة دائماً — حتى لو كانت النتيجة عنصراً واحداً أو صفراً. هذا لأن العلاقة قد تكون 1:كثير.
javascript
// النتيجة الفعلية:
{
_id: 'ObjectId("6520o1")',
orderNumber: "ORD-001",
user_id: 'ObjectId("6512a1")',
items: [...],
userDetails: [ // <- مصفوفة!
{
_id: 'ObjectId("6512a1")',
name: "جمال سالم",
email: "[email protected]",
...
}
]
}
// للوصول لعنصر واحد مباشرة -> استخدم $unwind
db.orders.aggregate([
{ $lookup: {...} },
{ $unwind: "$userDetails" } // <- يفكك المصفوفة
]);4. دمج $lookup مع $unwind
بعد $lookup، استخدم $unwind لتحويل المصفوفة إلى كائن مباشر.
javascript
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "user_id",
foreignField: "_id",
as: "userDetails"
}
},
{ $unwind: "$userDetails" }, // <- يفكك المصفوفة
{
$project: {
_id: 0,
orderNumber: 1,
customer: 1,
userEmail: "$userDetails.email",
userCountry: "$userDetails.country"
}
}
]);
// الآن userDetails كائن مباشر — أسهل في القراءة التطبيق العملي المباشر
تحدي الدرس الثالث: $lookup متقدم
قم بالتعديل على الكود بداخل المحرر أدناه لتطبيق المتطلبات التالية:
- طبّق
$lookupلربطordersمعusers. - غيّر اسم الحقل الناتج إلى
"customerInfo". - أضف
$unwindبعد$lookup. - أضف
$matchلفلترة الطلبات من السعودية أو مصر. - أضف
$projectلعرضorderNumberوcustomerوemailفقط.
⏳ جارٍ تحميل المحرر التفاعلي...