MongoDB / الأساسي: أسس الوثائق / الدرس 6
الإضافة والتحديث والحذف والمرشحات الذرية
اجعل الكتابة تعبر عن شروطها، وميز معاملات التحديث والاستبدال والإدراج عند الغياب والإقرار وهوية الإعادة.
في هذه الصفحة
أهداف الدرس
- استخدام CRUD محددة وتحديث حسابي شرطي.
- شرح ذرية الوثيقة ومعنى الطلب المكرر.
الوثيقة الواحدة حد الذرية الافتراضي
كتابة الوثيقة ذرية ولو تغيرت حقول عدة، ولا يعني ذلك ذرية updateMany على الجميع. قد تستبدل قراءة ثم كتابة مطلقة تغييراً متزامناً. ضع الحالة أو الإصدار في المرشح واستخدم $inc للحساب. افحص المطابقة والتعديل مع إقرار مناسب ولا تعد الرد إثبات الحدث.
أبقِ كفاية المخزون داخل التحديث
افترض الصنف 4 بكمية تسع. يخصم الأمر ثلاثاً عند الكفاية فيعطي ستاً. إذا كانت اثنتين فالمطابقة صفر ولا حجز. تفترض النتيجة نجاحاً مقراً وعينة معلومة، ونناقش الشبكة لاحقاً. يعطي الصنف الغائب صفراً أيضاً فميز الحالة عند حاجة الواجهة.
db.getSiblingDB('quay_lab').inventory.updateOne(
{ _id: 4, quantity: { $gte: 3 } },
{ $inc: { quantity: -3 } }
);
Expected with quantity initially 9: matchedCount = 1, modifiedCount = 1; quantity becomes 6.
يقيم شرط المخزون والحساب كتحديث وثيقة واحد.
يحذف الاستبدال الحقول العادية المهملة
تغير $set حقولاً مختارة وتستبدل replaceOne الجسم وفق _id ولا تحفظ المهمل. تضيف upsert عند غياب المطابقة وليست تجاهل أخطاء. يحتاج التزامن تفرداً مناسباً لمنع سجل منطقي مكرر. لا يجعل الفهرس الفريد زيادة الرصيد آمنة لحدث دفع معاد؛ ميز هوية المرجع والحدث.
استخدم فحص الحالة التفاؤلي بوعي
افترض الحجز 101 معلقاً بإصدار اثنين. يشترطهما المرشح قبل الإرسال ورفع الإصدار لثلاثة. إذا سبق الكاتب المنافس تفشل المطابقة. أعد القراءة والقرار ولا تحذف الفحص. هذا تزامن تفاؤلي لا معاملة للأنظمة الخارجية؛ تحتاج الرسالة outbox أو تكاملاً مراجعاً.
db.getSiblingDB('quay_lab').bookings.updateOne(
{ _id: 101, state: 'pending', version: 2 },
{ $set: { state: 'dispatched' }, $inc: { version: 1 } }
);
بعد مطابقة ناجحة تصبح الحالة dispatched والإصدار 3؛ لا يطابق الإصدار القديم.
اكتمال الدفعة ليس تراجعاً عن السابق
تتوقف الدفعة المرتبة عند خطأ بعد آثار ناجحة سابقة، وقد تواصل غير المرتبة دون ضمان ترتيب. ليستا معاملة كلية تلقائياً. راجع مرشح الحذف كالتحديث، خصوصاً المستأجر والفراغ. قد يترك خطأ الشبكة نتيجة مجهولة؛ استخدم إعادة المشغل الموثقة وهوية حدث تمنع مضاعفته.
الأخطاء الشائعة وإصلاحها
يكتب الحجز فوق كمية كاتب آخر
- لماذا يحدث؟
- جاءت القيمة المطلقة من قراءة قديمة.
- كيف تصلحه؟
- استخدم تحديثاً شرطياً أو إصداراً مراجعاً.
- كيف تتجنب تكراره؟
- ضع الثوابت والحالة المتوقعة داخل المرشح الذري.
تختفي حقول بعد replaceOne
- لماذا يحدث؟
- اختلط الاستبدال بتحديث $set الجزئي.
- كيف تصلحه؟
- استخدم المعاملات أو الجسم الكامل المقصود.
- كيف تتجنب تكراره؟
- راجع المهمل قبل اختيار طريقة الكتابة.
تترك دفعة مرتبة فاشلة آثاراً جزئية
- لماذا يحدث؟
- اعتُبر الوقوف تراجعاً عن السابق.
- كيف تصلحه؟
- صالح النتائج واستخدم معاملة إذا لزم عقدها المدعوم.
- كيف تتجنب تكراره؟
- اختبر الفشل الجزئي والتعافي بلا تكرار.
اختبر فهمك
1. المخزون اثنتان والطلب ثلاث. ما القرار الصحيح بعد التحديث الشرطي؟
اعرض الحل المشروح
لا مطابقة ولا حجز. أعد حالة عدم الكفاية أو الغياب حسب العقد دون إضعاف الشرط. قد ينجح طلب أصغر بالنمط نفسه. لا تحول الصفر إلى خصم بلا شرط فتزيل الحماية.
2. يعاد الدفع بعد فقد الرد. لماذا لا تكفي upsert على accountId؟
اعرض الحل المشروح
يعرف المفتاح الحساب لا الدفع فيكرر الزيادة. احفظ معرف حدث فريداً ونتيجته ونسق الأثر بالمعاملة أو نموذج الوثيقة. أعد النتيجة المعروفة عند التكرار بدلاً من تغيير مالي ثان.
أهم ما تعلمته
- لا تعني ذرية الوثيقة ذرية الدفعة أو الخارج.
- المرشح والإقرار وهوية الحدث من تصميم الكتابة.