MongoDB Academy · درس

تطوير المخططات دون توقف الخدمة

سيحدّث المتعلمون أداة تحقق موجودة في مجموعة قيد التشغيل، ويكتبون نصوص ترحيل لملء المستندات وفق البنية الجديدة.

الدرس 4 من 413 خطوة

تطوير المخططات دون توقف الخدمة درس مجاني في MongoDB Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في MongoDB Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة MongoDB Academy 4 دروس في المجموع.

تحدي تطوير المخطط

مع نمو تطبيقك، تتغير المتطلبات، ولذلك يجب أن يتطور مخطط MongoDB لديك. وعلى خلاف قواعد البيانات العلائقية، لا يمكنك تشغيل ALTER TABLE حاجب يقفل الجدول بأكمله أثناء الترحيل. وتتيح مرونة MongoDB تعايش أشكال المستندات القديمة والجديدة في المجموعة نفسها، ما يتطلب استراتيجية ترحيل مدروسة للحفاظ على عمل التطبيق أثناء انتقال المخطط.

الخطوة 1: تحديث أداة التحقق في وضع التحذير

ابدأ كل عملية ترحيل للمخطط بتحديث أداة التحقق الخاصة بالمجموعة لتعكس المخطط الجديد، مع استخدام validationAction: 'warn'. ويسمح ذلك ببقاء المستندات الحالية غير المتوافقة وتحديثها من دون أخطاء، مع قياس عدد المستندات التي تحتاج إلى ملء بياناتها. وستتوافق عمليات الكتابة الجديدة من شيفرة التطبيق المحدّثة مع المخطط الجديد.

// Add a new required field 'phoneNumber' to the validator
db.runCommand({
  collMod: 'users',
  validator: {
    $jsonSchema: {
      bsonType: 'object',
      required: ['name', 'email', 'phoneNumber'],
      properties: {
        name:        { bsonType: 'string' },
        email:       { bsonType: 'string' },
        phoneNumber: { bsonType: 'string' }
      }
    }
  },
  validationLevel: 'moderate',
  validationAction: 'warn'
});

الخطوة 2: تحديث شيفرة التطبيق

انشر شيفرة التطبيق المحدّثة التي تكتب مستندات متوافقة مع المخطط الجديد. وستتضمن المستندات الجديدة الحقول الجديدة. أما المستندات القديمة التي كُتبت قبل تغيير المخطط فستبقى في المجموعة بشكلها الأصلي. وخلال هذه المرحلة، يجب أن تتعامل شيفرة التطبيق مع شكلي المستندات، مثل توفير قيمة افتراضية عند غياب الحقل الجديد.

// Application code that handles both old and new document shapes
async function getUserPhone(userId) {
  const user = await db.collection('users').findOne({ _id: userId });
  // Provide a fallback for documents written before the migration
  return user.phoneNumber || 'Not provided';
}

الخطوة 3: كتابة نص لترحيل ملء البيانات

يتكرر نص ملء البيانات على جميع المستندات التي تفتقد إلى الحقل الجديد ويعيّن لها قيمة افتراضية. شغّله على دفعات صغيرة لتجنب قفل الموارد أو التسبب في ارتفاع مفاجئ في حمل الخادم. استخدم bulkWrite مع ordered: false لتحسين الكفاءة، وتابع التقدم عبر التسجيل كي تتمكن من الاستئناف إذا انقطعت العملية.

// Backfill: set phoneNumber to '' for documents that lack it
const collection = db.collection('users');
const cursor = collection.find({ phoneNumber: { $exists: false } });

const batchSize = 500;
let batch = [];

for await (const doc of cursor) {
  batch.push({
    updateOne: {
      filter: { _id: doc._id },
      update: { $set: { phoneNumber: '' } }
    }
  });
  if (batch.length === batchSize) {
    await collection.bulkWrite(batch, { ordered: false });
    console.log('Processed', batchSize, 'docs');
    batch = [];
  }
}
if (batch.length) await collection.bulkWrite(batch, { ordered: false });
console.log('Backfill complete');

الخطوة 4: التبديل إلى وضع الخطأ الصارم

بعد اكتمال ملء البيانات والتحقق من توافق جميع المستندات مع المخطط الجديد، اضبط validationLevel على strict وvalidationAction على error. ومن هذه النقطة فصاعدًا، سيُرفض أي إجراء كتابة يخالف المخطط. راقب التطبيق خلال الساعات الأولى بعد التبديل بحثًا عن أخطاء غير متوقعة، لاكتشاف أي حالة خاصة أغفلها ملء البيانات.

// Enable full enforcement after backfill is verified
db.runCommand({
  collMod: 'users',
  validationLevel: 'strict',
  validationAction: 'error'
});
console.log('Full schema enforcement enabled');

إعادة تسمية حقل بأمان

لإعادة تسمية حقل، مثل fullName → name، أضف أولًا name إلى المستندات الجديدة، مع استمرار التطبيق في قراءة fullName كخيار احتياطي. ثم املأ البيانات بنسخ fullName إلى name باستخدام $rename أو $set. وأخيرًا، حدّث التطبيق ليكتب name ويقرأه فقط، وأزل fullName من المستندات القديمة.

// Backfill: rename fullName to name for all existing documents
db.users.updateMany(
  { fullName: { $exists: true }, name: { $exists: false } },
  [{ $set: { name: '$fullName' } }, { $unset: 'fullName' }]
);

نمط إصدارات المخطط

في عمليات الترحيل المعقدة والطويلة، أضف حقل schemaVersion إلى كل مستند. وتتحقق شيفرة التطبيق من هذا الحقل وتطبق دالة تحويل لكل إصدار أقدم قبل معالجة المستند. وتتضمن عمليات الكتابة الجديدة دائمًا أحدث قيمة لـ schemaVersion. ويوفر ذلك مسار ترقية مضبوطًا وقابلًا للتدقيق، ويسمح بتعايش أجيال متعددة من المخطط إلى أجل غير مسمى.

// Insert new document with schema version
db.products.insertOne({
  schemaVersion: 2,
  name: 'Widget Pro',
  priceUSD: 49.99,
  categories: ['electronics']
});

// Application transformer
function normalise(doc) {
  if (doc.schemaVersion === 1) {
    // v1 used 'price' instead of 'priceUSD'
    doc.priceUSD = doc.price;
    delete doc.price;
    doc.schemaVersion = 2;
  }
  return doc;
}

إضافة حقل اختياري جديد بأمان

تُعد إضافة حقل اختياري جديد أبسط أشكال تطوير المخطط: حدّث properties في أداة التحقق من دون إضافة الحقل إلى required. ولا تحتوي المستندات الحالية على الحقل ببساطة، وتمر أداة التحقق عليها لأن الحقل غير مطلوب. ولا حاجة إلى ملء البيانات. ويمكن للمستندات الجديدة تضمين الحقل، فيما تقرؤه شيفرة التطبيق مع استخدام قيمة افتراضية احتياطية آمنة.

// Add optional 'avatarUrl' field to the validator
db.runCommand({
  collMod: 'users',
  validator: {
    $jsonSchema: {
      bsonType: 'object',
      required: ['name', 'email'],
      properties: {
        name:      { bsonType: 'string' },
        email:     { bsonType: 'string' },
        avatarUrl: { bsonType: 'string' }  // optional — no backfill needed
      }
    }
  }
});

إزالة حقل من المخطط

لإيقاف استخدام حقل، أزله أولًا من required إذا كان مطلوبًا، ثم انشر شيفرة التطبيق التي لم تعد تكتب الحقل. وبمرور الوقت، لن تتضمن المستندات الجديدة الحقل. ويمكنك اختياريًا ملء البيانات بإزالة الحقل من جميع المستندات الحالية باستخدام $unset، لكن لا يلزم ذلك إلا إذا كان الحقل يهدر مساحة تخزين أو يسبب التباسًا.

// Remove the deprecated 'legacyCode' field from all documents
db.products.updateMany(
  { legacyCode: { $exists: true } },
  { $unset: { legacyCode: '' } }
);

ملخص الترحيل من دون توقف الخدمة

تتمثل الفكرة الأساسية للترحيل من دون توقف الخدمة في أن MongoDB يسمح بتعايش أشكال مختلفة من المستندات في المجموعة نفسها. وهذا يعني أنك لا تحتاج مطلقًا إلى إيقاف قاعدة البيانات عن العمل لتغيير المخطط. وتفصل خطة المراحل الأربع — أداة تحقق في وضع التحذير، وتحديث شيفرة التطبيق، وملء البيانات، والفرض الصارم — تغيير المخطط عن عملية النشر، وتمنحك تحكمًا كاملًا في الجدول الزمني للانتقال.

التحقق من اكتمال الترحيل

قبل التبديل إلى الوضع الصارم، تحقق من عدم وجود أي مستند يفتقد إلى الحقول المطلوبة. ويؤكد استعلام عدّ بسيط اكتمال العملية. إذا كانت هناك مستندات لا تزال غير متوافقة، فشغّل نص ملء البيانات مرة أخرى. وتمنع خطوة التحقق هذه أخطاء التحقق المفاجئة بعد التبديل إلى إجراء error.

// Verify no users are missing the new required field
const missing = await db.collection('users').countDocuments({
  phoneNumber: { $exists: false }
});
console.log('Documents missing phoneNumber:', missing);
// Should be 0 before enabling strict enforcement

تحقق سريع

اختبر مدى فهمك لمفاهيم MongoDB وقواعد بيانات NoSQL التي تناولها هذا الدرس.

مراجعة الدرس

تعلمت في هذا الدرس أن: خطة الترحيل المؤلفة من أربع مراحل (تحذير → تحديث التطبيق → ملء البيانات → صارم) تحقق الترحيل من دون توقف الخدمة، وأن نمط إصدارات المخطط يتيح تعايش أشكال متعددة من المستندات إلى أجل غير مسمى، وأن التحقق قبل الفرض الصارم يمنع الأخطاء المفاجئة. بعد ذلك سنستكشف الإسقاط واختيار الحقول لجلب الحقول التي تحتاج إليها استعلاماتك فقط.

البدء مجانًا

تعلم JavaScript مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
30
الدروس
120

الأسئلة الشائعة

هل درس «تطوير المخططات دون توقف الخدمة» مجاني؟

نعم — نص درس «تطوير المخططات دون توقف الخدمة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة MongoDB Academy، انتقل إلى CoddyKit PRO. تتضمن دورة MongoDB Academy 4 دروس في المجموع.

ماذا ستتعلم في «تطوير المخططات دون توقف الخدمة»؟

سيحدّث المتعلمون أداة تحقق موجودة في مجموعة قيد التشغيل، ويكتبون نصوص ترحيل لملء المستندات وفق البنية الجديدة. تتمرن على MongoDB Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ MongoDB Academy؟

لا تُشترط خبرة سابقة. MongoDB Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «تطوير المخططات دون توقف الخدمة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس MongoDB Academy هذا؟

نعم. كل درس في MongoDB Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. إضافة أداة تحقق إلى مجموعة
  2. قيود النوع والمطلوب والقيم المحددة
  3. مستويات التحقق وإجراءاته
  4. تطوير المخططات دون توقف الخدمة
← العودة إلى MongoDB Academy