البحث في MongoDB: find والمعاملات
تخيّل أنك أمين المكتبة، والزوار يسألونك: «أريد كتب التقنية»، «ما الكتب التي صفحاتها أكثر من 200؟»، «ما أحدث كتابين؟». في MongoDB، كل سؤال من هذه يتحول إلى استعلام find. وفي هذا الدرس ستتعلم كيف تكتب هذه الاستعلامات، وستلاحظ أن لغة البحث نفسها مستند يصف ما تبحث عنه.
سنعمل على الكتب الخمسة التي أضفناها في الدرس السابق: رحلة إلى القمر (2020)، وأسرار البحار (2018)، والبرمجة للمبتدئين (2023، غير متاح)، وحكايات جدتي (2015)، وعالم الروبوتات (2022).
find والإسقاط
Section titled “find والإسقاط”db.books.find({}, { title: 1, year: 1, _id: 0 })[ { title: 'رحلة إلى القمر', year: 2020 }, { title: 'أسرار البحار', year: 2018 }, { title: 'البرمجة للمبتدئين', year: 2023 }, { title: 'حكايات جدتي', year: 2015 }, { title: 'عالم الروبوتات', year: 2022 }]find تأخذ معاملين:
- الفلتر: أي المستندات تريد.
{}الفارغ يعني «كلها». - الإسقاط (Projection): أي الحقول تعرض.
1يعني «اعرض»، و_id: 0يعني «أخفِ المعرّف» لأنه يظهر افتراضياً.
بدون الإسقاط تظهر المستندات كاملة بكل حقولها. والإسقاط مثل SELECT title, year في SQL.
البحث بالمساواة
Section titled “البحث بالمساواة”db.books.find({ available: false }, { title: 1, _id: 0 })[ { title: 'البرمجة للمبتدئين' } ]الفلتر { available: false } يعني «حيث available تساوي false». الاستعلام مستند يشبه المستندات التي تبحث عنها.
معاملات المقارنة
Section titled “معاملات المقارنة”للمقارنات غير المساواة، تستخدم معاملات تبدأ بعلامة $:
db.books.find({ pages: { $gt: 200 } }, { title: 1, pages: 1, _id: 0 })[ { title: 'أسرار البحار', pages: 240 }, { title: 'البرمجة للمبتدئين', pages: 320 }, { title: 'عالم الروبوتات', pages: 210 }]| المعامل | المعنى |
|---|---|
$eq و $ne |
يساوي، لا يساوي |
$gt و $gte |
أكبر من، أكبر من أو يساوي |
$lt و $lte |
أصغر من، أصغر من أو يساوي |
$in و $nin |
ضمن قائمة، ليس ضمن قائمة |
الحروف اختصارات إنجليزية: gt من greater than، و lt من less than، و e في gte من equal.
دمج الشروط
Section titled “دمج الشروط”و (AND): ضع الشروط في نفس المستند، وتُدمج تلقائياً:
db.books.find( { price: { $gte: 50, $lte: 120 }, available: true }, { title: 1, price: 1, _id: 0 })[ { title: 'رحلة إلى القمر', price: 75.5 }, { title: 'أسرار البحار', price: 90 }]السعر بين 50 و 120 و الكتاب متاح. «البرمجة للمبتدئين» سعره 120 لكنه غير متاح، فاستُبعد.
ضمن قائمة: $in
db.books.find({ year: { $in: [2015, 2023] } }, { title: 1, year: 1, _id: 0 })[ { title: 'البرمجة للمبتدئين', year: 2023 }, { title: 'حكايات جدتي', year: 2015 }]أو (OR): المعامل $or مع مصفوفة شروط:
db.books.find( { $or: [ { pages: { $lt: 100 } }, { price: { $gt: 140 } } ] }, { title: 1, _id: 0 })[ { title: 'حكايات جدتي' }, { title: 'عالم الروبوتات' } ]كتاب قصير (أقل من 100 صفحة) أو غالٍ (أكثر من 140).
البحث في المصفوفات
Section titled “البحث في المصفوفات”هنا تتفوق MongoDB. ابحث عن قيمة داخل مصفوفة كأنها حقل عادي:
db.books.find({ genres: 'تقنية' }, { title: 1, _id: 0 })[ { title: 'البرمجة للمبتدئين' }, { title: 'عالم الروبوتات' } ]genres مصفوفة، لكن MongoDB تفهم أنك تقصد: «الكتب التي تحتوي مصفوفة تصنيفاتها على “تقنية”». لا JOIN ولا جداول إضافية.
البحث في الحقول المتداخلة
Section titled “البحث في الحقول المتداخلة”استخدم النقطة للوصول إلى حقل داخل مستند متداخل، مع وضع الاسم بين علامتي تنصيص:
db.books.find({ 'publisher.country': 'الأردن' }, { title: 1, 'publisher.name': 1, _id: 0 })[ { title: 'أسرار البحار', publisher: { name: 'دار المعرفة' } }, { title: 'عالم الروبوتات', publisher: { name: 'دار المعرفة' } }]الترتيب والتحديد: sort و limit و skip
Section titled “الترتيب والتحديد: sort و limit و skip”db.books.find({}, { title: 1, price: 1, _id: 0 }).sort({ price: -1 }).limit(2)[ { title: 'عالم الروبوتات', price: 150 }, { title: 'البرمجة للمبتدئين', price: 120 }]sort({ price: -1 }): رتّب بالسعر تنازلياً، و1للتصاعدي.limit(2): خذ أول نتيجتين فقط.skip(n): تخطَّ أولnنتائج، ومعlimitتصنع صفحات النتائج.
findOne و countDocuments
Section titled “findOne و countDocuments”db.books.findOne({ author: 'منى علي' }, { title: 1, _id: 0 }){ title: 'البرمجة للمبتدئين' }findOne تُرجع أول مستند مطابق كمستند مباشر (لا كمصفوفة)، أو null إذا لم تجد شيئاً. و db.books.countDocuments({ available: true }) تعدّ المطابقين، والناتج هنا 4.
جرّب بنفسك
Section titled “جرّب بنفسك”على مجموعة الكتب:
- اعرض عناوين الكتب المنشورة بعد 2019 فقط.
- اعرض الكتب المتاحة التي سعرها أقل من 100.
- اعرض كتب تصنيف «مغامرات».
- اعرض الكتب الصادرة عن ناشرين من مصر.
- اعرض أقدم كتابين بالعنوان والسنة فقط.
- تحدٍّ: اعرض الكتب التي تصنيفها «علوم» أو عدد صفحاتها أقل من 100.
أخطاء شائعة
Section titled “أخطاء شائعة”- نسيان علامتي التنصيص مع النقطة:
{ publisher.country: '...' }خطأ في الصياغة. الصحيح{ 'publisher.country': '...' }. - نسيان $ في المعاملات:
{ pages: { gt: 200 } }تبحث عن مستند حقلpagesفيه يساوي{ gt: 200 }حرفياً، فلا تجد شيئاً بصمت. - خلط الإسقاط: لا تخلط
1و0في نفس الإسقاط، إلا مع_id: 0.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
أي فلتر يجد الكتب التي صفحاتها أقل من 150؟
المعامل يُكتب داخل مستند قيمة الحقل: { الحقل: { $lt: القيمة } }.
سؤال
الحقل tags مصفوفة. ماذا يجد الاستعلام find({ tags: 'جديد' })؟
MongoDB يبحث داخل المصفوفات تلقائياً، فيطابق أي مستند تحتوي مصفوفته على القيمة.
الخلاصة
Section titled “الخلاصة”find(فلتر, إسقاط): الفلتر يحدد المستندات، والإسقاط يحدد الحقول.- المعاملات
$gtو$ltو$gteو$lteو$inو$neللمقارنات. - الشروط في نفس المستند تعني AND، و
$orلـ OR. - البحث في المصفوفات مباشر، والحقول المتداخلة بالنقطة بين علامتي تنصيص.
sortوlimitوskipللترتيب والصفحات، وfindOneوcountDocumentsللمستند الواحد والعدد.