NoSQL Databases • المستوى الثاني • الدرس 4
العودة لفهرس المستوىالتصفية المتقدمة داخل المصفوفات ($elemMatch)
أهداف الدرس
- استخدام
$elemMatchللبحث بشرطين معاً على نفس الكائن بداخل المصفوفة. - تجنب أخطاء الفلترة العامة على المصفوفات المضمنة.
- دمج
$elemMatchمع معاملات المقارنة ($gt،$gte،$lt). - تطبيق
$elemMatchفي أنظمة الطلبات والتجارة الإلكترونية.
1. المشكلة بدون $elemMatch
تخيّل أن لديك مصفوفة items بداخل مستند الطلب، كل عنصر يمثل منتجاً:
javascript
{
orderNumber: "ORD-002",
customer: "أحمد علي",
items: [
{ product_id: 101, name: "لابتوب", quantity: 5, price: 1500 },
{ product_id: 103, name: "كيبورد", quantity: 2, price: 200 }
]
}الاستعلام الخاطئ الشائع
db.orders.find({
"items.product_id": 101,
"items.quantity": { $gt: 4 }
});هذا الاستعلام يبحث عن أي طلب يحتوي على:
- product_id: 101 في أي عنصر، و
- quantity > 4 في أي عنصر (ربما مختلف!)
النتيجة: قد يُطابق طلباً ليس فيه لابتوب بكمية كبيرة أصلاً!
2. الحل — $elemMatch
$elemMatch يضمن أن جميع الشروط تتحقق على نفس العنصر داخل المصفوفة:
javascript
db.orders.find({
items: {
$elemMatch: {
product_id: 101,
quantity: { $gt: 4 }
}
}
});
// النتيجة: فقط الطلبات التي فيها
// "لابتوب بكمية > 4" في نفس عنصر المصفوفةبدون $elemMatch
الشروط تُطبَّق على عناصر مختلفة — نتائج غير دقيقة.
مع $elemMatch
كل الشروط تُطبَّق على نفس العنصر — نتائج دقيقة.
3. دمج $elemMatch مع معاملات المقارنة
$gt — أكبر من
quantity: { $gt: 5 }$gte — أكبر أو يساوي
quantity: { $gte: 5 }$lt — أصغر من
quantity: { $lt: 3 }شرطان على نفس الحقل
quantity: { $gt: 2, $lt: 6 }4. استخدامات واقعية
1.التجارة الإلكترونية: الطلبات التي فيها منتج معيّن بكمية محددة.
2.أنظمة التوظيف: المرشحون بمهارة معيّنة ومستوى خبرة محدد.
3.التعليم: الطلاب الذين حصلوا على درجة محددة في مادة معيّنة.
التطبيق العملي المباشر
تحدي الدرس الرابع: $elemMatch متقدم
قم بالتعديل على الكود بداخل المحرر أدناه لتطبيق المتطلبات التالية:
- غيّر شرط الكمية من
$gt: 2إلى$gt: 5. - أضف استعلاماً جديداً للبحث عن
product_id: 102بـ$gte: 5. - أضف استعلاماً مع
ProjectionلعرضorderNumberوcustomerفقط. - اعرض جميع الطلبات بـ
db.orders.find({}). - اطبع عدد الطلبات الإجمالي بـ
countDocuments().
⏳ جارٍ تحميل المحرر التفاعلي...