مقدمة في MongoDB — MongoDB
مقدمة في MongoDB
MongoDB قاعدة بيانات مستندات: بدل الصفوف والأعمدة، تخزن مستندات تشبه كائنات JSON، داخل مجموعات.
SQL: قاعدة بيانات ← جداول ← صفوف ← أعمدة
MongoDB: قاعدة بيانات ← مجموعات (collections) ← مستندات (documents) ← حقولالمستند
const user = {
_id: "6714f0c2a1b2c3d4e5f60718", // ObjectId يولّده MongoDB تلقائياً
name: "سارة",
email: "sara@example.com",
tags: ["مبتدئ", "بايثون"], // مصفوفة داخل المستند
address: { city: "بغداد", street: "الكرادة" }, // مستند متداخل
createdAt: new Date("2026-10-01T09:00:00Z"),
};
console.log(Object.keys(user));- يُخزَّن بصيغة BSON (JSON ثنائي بأنواع إضافية: تواريخ حقيقية، أرقام صحيحة وعشرية، ObjectId، بيانات ثنائية).
- _id إلزامي وفريد في المجموعة. الـ ObjectId الافتراضي (12 بايتاً) يحتوي وقت الإنشاء، فالترتيب به يقارب الترتيب الزمني.
- المستندات في نفس المجموعة لا تُلزم بنفس الحقول — مرونة، ومسؤولية عليك (درس Mongoose والتحقق).
- حد حجم المستند 16MB.
متى MongoDB ومتى SQL؟
| يميل لـ MongoDB | يميل لـ SQL (PostgreSQL) |
|---|---|
| البيانات تُقرأ ككتلة واحدة (منشور بتعليقاته الأولى، كتالوج منتجات بخصائص مختلفة) | علاقات كثيرة متشابكة وتقارير بربط جداول متعددة |
| شكل البيانات يتغير كثيراً أو يختلف بين العناصر | قيود صارمة وسلامة مالية (ACID عبر جداول كثيرة) |
| توسع أفقي ضخم للكتابة | فريق يعرف SQL، وأدوات تحليل وتقارير |
كلاهما ناضج وقادر. PostgreSQL مع JSONB يغطي كثيراً من حالات المستندات، و MongoDB يدعم المعاملات والتحقق من المخطط. اختر حسب أنماط القراءة والكتابة في تطبيقك، لا حسب الموضة.
المشغّل الرسمي (MongoDB Driver)
المثال الكامل يتصل بالمشغّل الرسمي وينفذ CRUD:
| العملية | الدالة | ملاحظات |
|---|---|---|
| إدراج | insertOne / insertMany | يعيد insertedId |
| قراءة | findOne / find().toArray() | find يعيد مؤشراً؛ toArray يحمّل كل النتائج في الذاكرة — استخدم limit |
| تحديث | updateOne / updateMany مع $set و $inc | بدون عامل ($set) تستبدل المستند كله! |
| حذف | deleteOne / deleteMany | deleteMany({}) تحذف الكل |
الاتصال الصحيح
- عميل واحد (MongoClient) للتطبيق كله يُنشأ عند البدء: يدير مجمّع اتصالات داخلياً. إنشاء عميل لكل طلب يستنزف الاتصالات.
- رابط الاتصال في متغيرات البيئة (MONGODB_URI) — فيه اسم المستخدم وكلمة المرور.
- في MongoDB Atlas (الخدمة السحابية) قيّد عناوين IP المسموحة، واستخدم مستخدماً بصلاحيات قاعدة التطبيق فقط.
الأمان من البداية
المدخلات قد تحمل عوامل: { email: req.body.email } حيث req.body.email = { "$ne": null } يطابق أول مستخدم. حوّل المدخلات لأنواعها (String(...)) أو فعّل sanitizeFilter في Mongoose (الدروس القادمة).
تمرين
أنشئ حساباً مجانياً في MongoDB Atlas (أو شغّل MongoDB محلياً)، وشغّل المثال الكامل بعد وضع الرابط في MONGODB_URI. ثم أضف createdAt لكل مستند، واطلب آخر 5 مستخدمين مرتبين تنازلياً بـ sort و limit.
// تثبيت MongoDB driver
// npm install mongodb
const { MongoClient } = require('mongodb');
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);
async function main() {
try {
// الاتصال
await client.connect();
console.log('متصل بـ MongoDB!');
// اختيار Database و Collection
const db = client.db('myapp');
const users = db.collection('users');
// ===== Insert =====
// واحد
const result = await users.insertOne({
name: 'أحمد',
email: 'ahmed@mail.com',
age: 25
});
console.log('ID:', result.insertedId);
// متعدد
await users.insertMany([
{ name: 'سارة', age: 22 },
{ name: 'محمد', age: 30 }
]);
// ===== Find =====
// واحد
const user = await users.findOne({ email: 'ahmed@mail.com' });
console.log(user);
// الكل
const allUsers = await users.find({}).toArray();
console.log(allUsers);
// مع شروط
const youngUsers = await users.find({ age: { $lt: 25 } }).toArray();
// ===== Update =====
await users.updateOne(
{ email: 'ahmed@mail.com' },
{ $set: { age: 26 } }
);
// ===== Delete =====
await users.deleteOne({ email: 'ahmed@mail.com' });
} finally {
await client.close();
}
}
main().catch(console.error);اختبر فهمك