كيفية استخدام $ lookup في MongoDB

MongoDB هي قاعدة بيانات NoSQL شائعة تخزن البيانات في مجموعات. تتكون مجموعات MongoDB من مستند واحد أو أكثر تحتوي على البيانات الفعلية بتنسيق JSON. المستندات قابلة للمقارنة مع الصفوف في قواعد بيانات SQL العلائقية التقليدية ، بينما المجموعات مماثلة للجداول.
الوظيفة الرئيسية في قواعد البيانات هي القدرة على الاستعلام عن البيانات المخزنة في قاعدة البيانات. يسمح الاستعلام عن البيانات باسترجاع معلومات محددة ، وتحليل البيانات ، وإبلاغ البيانات ، وكذلك تكامل البيانات.
لتكون قادرًا على الاستعلام عن قاعدة بيانات بشكل فعال ، من الضروري أن تكون قادرًا على دمج البيانات من جداول متعددة ، في حالة قواعد بيانات SQL أو مجموعات متعددة في قواعد بيانات NOSQL ، في مجموعة نتائج واحدة.
في MongoDB $ lookup يقوم المستخدمون بدمج المعلومات من مجموعتين عند الاستعلام. ينفذ ما يعادل الصلة الخارجية اليسرى في قاعدة بيانات SQL.
استخدام وأهداف $ lookup
من الوظائف المهمة لقواعد البيانات معالجة البيانات للحصول على معلومات مفيدة من البيانات الأولية.
على سبيل المثال ، إذا كنت تدير مطعمًا تجاريًا ، فقد ترغب في تحليل بيانات مطعمك لمعرفة مقدار ما تجنيه يوميًا ، أو الأطعمة المطلوبة في عطلات نهاية الأسبوع ، أو حتى معرفة عدد أكواب القهوة التي تبيعها في كل ساعة من اليوم.
لمثل هذه الاحتياجات ، لن تكفي استعلامات قاعدة البيانات البسيطة. تحتاج إلى إجراء استعلامات متقدمة على البيانات التي قمت بتخزينها. لتلبية هذه الاحتياجات ، لدى MongoDB ميزة تسمى خط أنابيب التجميع.
خط أنابيب التجميع هو نظام يتألف من عمليات قابلة للإنشاء تسمى المراحل ، والتي تُستخدم لمعالجة البيانات لإنتاج نتيجة مجمعة نهائية. تتضمن أمثلة المراحل في خط أنابيب التجميع $ sort و $ match و $ group و $ merge و $ count و $ lookup ، من بين أمور أخرى.
يمكن تطبيق هذه المراحل بأي ترتيب في خط أنابيب التجميع. في كل مرحلة في خط أنابيب التجميع ، يتم إجراء عمليات مختلفة على البيانات التي يتم تمريرها عبر خط أنابيب التجميع.
وبالتالي فإن $ lookup هي مرحلة في خط أنابيب تجميع MongoDB. يتم استخدام $ Lookup لتنفيذ صلة خارجية يسرى بين مجموعتين في قاعدة بيانات MongoDB. تدمج الصلة الخارجية اليسرى جميع المستندات أو الإدخالات الموجودة على اليسار مع المستندات أو الإدخالات المتطابقة على اليمين.
على سبيل المثال ، ضع في اعتبارك المجموعتين أدناه ، اللتين تم تمثيلهما بتنسيق جدولي لتسهيل الفهم:
أوامر_جمع:
order_idcustomer_idorder_datetetotal_amount11002022-05-0150.0021012022-05-0275.0031022022-05-03100.00
customers_collection:
customer_numcustomer_namecustomer_emailcustomer_phone100 جون [email protected] [email protected]
إذا قمنا بإجراء صلة خارجية على اليسار على المجموعات المذكورة أعلاه باستخدام حقل customer_id ، الذي يظهر في order_collection ، مع كون مجموعة order_collection هي المجموعة اليسرى ومجموعة customers_collection هي المجموعة الصحيحة ، فستحتوي النتيجة على جميع المستندات في مجموعة الطلبات والمستندات في مجموعة العملاء التي تحتوي على رقم زبون يتطابق مع معرف العميل لأي من السجلات الموجودة في مجموعة الطلبات.
تبدو النتيجة النهائية لعملية الانضمام الخارجي الأيسر على الطلبات ومجموعات العملاء على هذا النحو عند تمثيلها في تنسيق جدولي:
لاحظ أنه بالنسبة للعميل الذي يحتوي على customer_id 101 في مجموعة الطلبات ، والذي لا يحتوي على قيمة customer_num متطابقة في مجموعة العملاء ، فإن القيم المقابلة المفقودة من جدول العميل قد تم ملؤها فارغة.
يقوم $ lookup بإجراء مقارنة صارمة للمساواة بين الحقول واسترداد المستند المطابق بالكامل وليس فقط الحقول المتطابقة.
بناء الجملة $ lookup
بناء جملة $ lookup كما يلي:
{ $lookup: { from: <collection to join>, localField: <field from the input documents>, foreignField: <field from the documents of the "from" collection>, as: <output array field> } }
يحتوي $ lookup على أربع معاملات:
- من – يمثل المجموعة التي نريد البحث عن المستندات منها. في مثالنا السابق باستخدام orders_collection و customers_collection ، وضعنا customers_collection على أنها من المجموعة.
- localField – هذا حقل في المجموعة العاملة أو الأولية التي نستخدمها للمقارنة بالحقول الموجودة في مجموعتنا (customers_collection في حالتنا). في المثال أعلاه ، سيكون المجال المحلي هو customer_id الموجود في مجموعة orders_collection.
- ForeignField – هذا هو الحقل الذي نريد مقارنته في المجموعة التي نحددها من. في مثالنا ، سيكون هذا هو customer_num الموجود في customer_collection الذي نستخدمه كقيمة في from
- كـ – هذا اسم حقل جديد نحدده لتمثيل الحقل الذي سيظهر في وثيقتنا ، والذي يحتوي على مستندات ناتجة عن التطابقات بين localField والحقل الأجنبي. يتم وضع كل هذه التطابقات في مصفوفة في هذا المجال. إذا لم تكن هناك مطابقات ، فسيحتوي هذا الحقل على مصفوفة فارغة.
من مجموعتنا السابقة ، سنستخدم الكود التالي لإجراء عملية بحث بالدولار على المجموعتين مع مجموعة orders_collection كمجموعة عمل أو مجموعة أساسية.
{ $lookup: { from: "customers_collection", localField: "customer_id", foreignField: "customer_num", as: "customer_info" }
لاحظ أن الحقل as يمكن أن يكون أي قيمة سلسلة. ومع ذلك ، إذا أعطيته اسمًا موجودًا بالفعل في مستند العمل ، فسيتم الكتابة فوق هذا الحقل.
ضم البيانات من مجموعات متعددة
يعتبر MongoDB $ lookup مرحلة مفيدة في خط أنابيب التجميع في MongoDB. على الرغم من أنه ليس من المتطلبات أن يكون لخط أنابيب التجميع في MongoDB مرحلة بحث بالدولار ، إلا أن المرحلة مهمة عند إجراء استعلامات معقدة تتطلب ضم البيانات عبر مجموعات متعددة.
تقوم مرحلة البحث $ بتنفيذ صلة خارجية يسرى على مجموعتين مما يؤدي إلى إنشاء حقل جديد أو الكتابة فوق قيم حقل موجود بمصفوفة تحتوي على مستندات من مجموعة أخرى.
يتم تحديد هذه المستندات بناءً على ما إذا كانت تحتوي على قيم تطابق قيم الحقل التي تتم مقارنتها به. النتيجة النهائية هي حقل يحتوي على مجموعة من المستندات في حالة العثور على مطابقات أو مصفوفة فارغة في حالة عدم العثور على مطابقات.
ضع في اعتبارك مجموعات الموظفين والمشاريع الموضحة أدناه.
يمكننا استخدام الكود التالي للانضمام إلى المجموعتين:
db.projects.aggregate([ { $lookup: { from: "employees", localField: "employees", foreignField: "_id", as: "assigned_employees" } } ])
نتيجة هذه العملية هي مزيج من المجموعتين. والنتيجة هي المشاريع وجميع الموظفين المعينين لكل مشروع. يتم تمثيل الموظفين في مصفوفة.
مراحل خط الأنابيب التي يمكن استخدامها مع $ lookup
كما ذكرنا سابقًا ، فإن $ lookup هي مرحلة في خط أنابيب تجميع MongoDB ، ويمكن استخدامها مع مراحل خطوط تجميع أخرى. لإظهار كيف يمكن استخدام هذه المراحل مع $ lookup ، سنستخدم المجموعتين التاليتين لأغراض التوضيح.
في MongoDB ، يتم تخزينها بتنسيق JSON. هذا ما تبدو عليه المجموعات أعلاه في MongoDB.
تتضمن بعض الأمثلة على مراحل خطوط أنابيب التجميع التي يمكن استخدامها مع $ lookup ما يلي:
مباراة $
مطابقة $ هي مرحلة خط أنابيب تجميع تُستخدم لتصفية تدفق المستند للسماح فقط لتلك المستندات التي تفي بالشرط المحدد بالمتابعة إلى المرحلة التالية في خط أنابيب التجميع. من الأفضل استخدام هذه المرحلة في وقت مبكر من خط الأنابيب لإزالة المستندات التي لن تكون ضرورية وبالتالي تحسين خط أنابيب التجميع.
باستخدام المجموعتين السابقتين ، يمكنك الجمع بين $ match و $ lookup على النحو التالي:
db.users.aggregate([ { $match: { country: "USA" } }, { $lookup: { from: "orders", localField: "_id", foreignField: "user_id", as: "orders" } } ])
يتم استخدام $ match لتصفية المستخدمين من الولايات المتحدة الأمريكية. ثم يتم دمج النتيجة من $ match مع $ lookup للحصول على تفاصيل طلبات المستخدمين من الولايات المتحدة الأمريكية. نتيجة العملية المذكورة أعلاه موضحة أدناه:
مشروع $
مشروع $ هي مرحلة تُستخدم لإعادة تشكيل المستندات عن طريق تحديد الحقول المراد تضمينها أو استبعادها أو إضافتها إلى المستندات. على سبيل المثال ، إذا كنت تقوم بمعالجة مستندات تحتوي على عشرة حقول لكل منها ، لكن أربعة حقول فقط في المستندات تحتوي على البيانات التي تحتاجها لمعالجة بياناتك ، يمكنك استخدام مشروع $ لتصفية الحقول الخارجية التي لا تحتاج إليها.
يتيح لك ذلك تجنب إرسال البيانات غير الضرورية إلى المرحلة التالية من خط أنابيب التجميع.
يمكننا الجمع بين $ lookup و $ project مثل:
db.users.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "user_id", as: "orders" } }, { $project: { name: 1, _id: 0, total_spent: { $sum: "$orders.price" } } } ])
يجمع ما ورد أعلاه بين مجموعات المستخدمين والأوامر باستخدام $ lookup ، ثم يتم استخدام $ project لعرض اسم كل مستخدم والمبلغ الذي ينفقه كل مستخدم فقط. يتم استخدام مشروع $ أيضًا لإزالة الحقل _id من النتائج. نتيجة العملية المذكورة أعلاه موضحة أدناه:
استرخاء
الاسترخاء $ هي مرحلة تجميع تُستخدم لتفكيك أو فك حقل مصفوفة لإنشاء مستندات جديدة لكل عنصر في المصفوفة. هذا مفيد في حالة رغبتك في تشغيل بعض التجميع على قيم حقل الصفيف.
على سبيل المثال ، في المثال أدناه ، إذا كنت تريد تشغيل التجميع في مجال الهوايات ، فلا يمكنك القيام بذلك لأنه مصفوفة. ومع ذلك ، يمكنك استخدام ميزة “فك الارتباط” باستخدام $ “فك” ثم إجراء التجميعات على المستندات الناتجة.
باستخدام مجموعات المستخدمين والأوامر ، يمكننا استخدام $ lookup و $ relaxing معًا كما يلي:
db.users.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "user_id", as: "orders" } }, { $unwind: "$orders" } ])
في الكود أعلاه ، يقوم $ lookup بإرجاع حقل مصفوفة يسمى الطلبات. ثم يتم استخدام $ الاسترخاء لفك مجال الصفيف. تظهر نتيجة هذه العملية أدناه: لاحظ ظهور أليس مرتين لأنها حصلت على أمرين.
أمثلة على حالات استخدام $ lookup
عند إجراء معالجة البيانات ، يعد $ lookup أداة مفيدة. على سبيل المثال ، قد يكون لديك مجموعتان تريد الانضمام إليهما بناءً على الحقول الموجودة في المجموعات التي تحتوي على بيانات متشابهة. يمكن استخدام مرحلة بحث $ بسيطة للقيام بذلك وإضافة حقل جديد في المجموعات الأولية ، والتي تحتوي على مستندات تم الحصول عليها من مجموعة أخرى.
تعتبر مجموعات المستخدمين والأوامر الموضحة أدناه:
يمكن دمج المجموعتين باستخدام $ lookup لإعطاء النتيجة الموضحة أدناه:
يمكن أيضًا استخدام $ lookup لإجراء صلات أكثر تعقيدًا. لا يقتصر $ lookup على أداء الانضمام إلى مجموعتين فقط. يمكنك تنفيذ عدة مراحل بحث $ لتنفيذ الصلات على أكثر من مجموعتين. ضع في اعتبارك المجموعات الثلاث الموضحة أدناه:
يمكننا استخدام الكود أدناه لإجراء انضمام أكثر تعقيدًا عبر المجموعات الثلاث للحصول على جميع الطلبات التي تم إجراؤها وكذلك تفاصيل المنتجات التي تم طلبها.
يسمح لنا الكود أدناه بالقيام بذلك:
db.orders.aggregate([ { $lookup: { from: "order_items", localField: "_id", foreignField: "order_id", as: "order_items" } }, { $unwind: "$order_items" }, { $lookup: { from: "products", localField: "order_items.product_id", foreignField: "_id", as: "product_details" } }, { $group: { _id: "$_id", customer: { $first: "$customer" }, total: { $sum: "$order_items.price" }, products: { $push: "$product_details" } } } ])
نتيجة العملية المذكورة أعلاه موضحة أدناه:
خاتمة
عند إجراء معالجة البيانات التي تتضمن مجموعات متعددة ، يمكن أن يكون $ lookup مفيدًا لأنه يسمح لك بضم البيانات واستخلاص النتائج بناءً على البيانات المخزنة في مجموعات متعددة. نادرًا ما تعتمد معالجة البيانات على مجموعة واحدة فقط.
لاستخلاص استنتاجات ذات مغزى من البيانات ، يعد ضم البيانات عبر مجموعات متعددة خطوة أساسية. لذلك ، ضع في اعتبارك استخدام مرحلة $ lookup في خط تجميع MongoDB للسماح لك بمعالجة بياناتك بشكل أفضل واستخلاص رؤى ذات مغزى من البيانات الأولية المخزنة عبر المجموعات.
يمكنك أيضًا استكشاف بعض أوامر واستعلامات MongoDB.