تتيح ميزة "تغيير مصادر البيانات" في Firestore المتوافقة مع MongoDB للتطبيقات الوصول إلى التغييرات في الوقت الفعلي (عمليات الإدراج والتعديل والحذف) التي يتم إجراؤها على مجموعة أو على قاعدة بيانات بأكملها. يرتّب مصدر بيانات التغييرات التعديلات حسب وقت التعديل.
يمكن الوصول إلى مصادر بيانات التغييرات من خلال واجهات برمجة التطبيقات المتوافقة مع MongoDB وبرامج تشغيل MongoDB التقليدية. يمكن لتنفيذ ميزة "تغيير مصادر البيانات" في Firestore المتوافقة مع MongoDB التعامل مع أي معدّل نقل للعمليات التي يتم إجراؤها على الكتابة والقراءة من خلال تنفيذ فريد لعملية التقسيم التلقائي عند الكتابة والقراءة المتوازية. يتيح لك ذلك إنشاء أحمال عمل ذات معدّل نقل عالٍ. يمكنك أيضًا تحسين البنية الأساسية لترحيل البيانات ومزامنتها بين Cloud Firestore وحلول التخزين الأخرى.
بالإضافة إلى التوافق مع برامج تشغيل MongoDB، يمكنك استخدام Cloud Firestore لقراءة مصادر بيانات التغييرات بالتوازي. يتيح لك ذلك إنشاء أحمال عمل متوازية للقراءة ذات معدّل نقل عالٍ. يمثّل كل مصدر بيانات قسمًا موزّعًا بشكل جيد من النتائج.
تتيح ميزة "تغيير مصادر البيانات" الميزات التالية:
- مصادر بيانات تغيير قابلة للضبط مع نطاق قاعدة البيانات أو المجموعة
- مدة الاحتفاظ بمصدر بيانات التغيير المحدّدة عند الإنشاء مدة الاحتفاظ التلقائية هي 7 أيام والحد الأدنى لمدة الاحتفاظ هو يوم واحد. يجب أن تكون مدة الاحتفاظ من مضاعفات يوم واحد، بحد أقصى 7 أيام. لا يمكن تغيير مدة الاحتفاظ بعد الإنشاء. لتغيير مدة الاحتفاظ، عليك حذف مصدر بيانات التغيير وإعادة إنشائه.
- أحداث التغيير
deleteوinsertوupdateوdropالتي يمكن ملاحظتها باستخدامdb.collection.watch()وdb.watch() - يحتوي
updateDescription.updatedFieldsعلى اختلافات التعديل. - جميع الخيارات
fullDocumentوfullDocumentBeforeChange- البحث عن المستند الكامل للتعديلات
- الصورة المسبقة للمستند قبل استبداله أو تعديله أو حذفه
- الصورة اللاحقة للمستند بعد استبداله أو تعديله
- تتطلب الصور المسبقة واللاحقة التي يزيد عمرها عن ساعة واحدة تفعيل ميزة "الاسترداد في نقطة زمنية" (PITR).
- جميع خيارات الاستئناف، بما في ذلك
resumeAfterوstartAfter - عند استخدام
watch()لملاحظة التغييرات، يمكنك ربط مراحل التجميع، مثل$addFieldsو$matchو$projectو$replaceRootو$replaceWithو$setو$unset.
ضبط ميزة "تغيير مصادر البيانات"
لإنشاء مصادر بيانات تغيير حالية أو حذفها أو عرضها لقاعدة بيانات، استخدِم Google Cloud Console.
الأدوار والأذونات
لإنشاء مصادر بيانات تغيير وحذفها وإدراجها، يحتاج كيان أساسي إلى أذونات "إدارة الهوية وإمكانية الوصول" (IAM) التالية على التوالي: datastore.schemas.create وdatastore.schemas.delete وdatastore.schemas.list.
على سبيل المثال، يمنح دور مشرف فهرس Datastore (roles/datastore.indexAdmin) هذه الأذونات.
إنشاء مصدر بيانات تغيير
قبل أن تتمكّن من فتح مؤشر مصدر بيانات تغيير مطابق، عليك إنشاء مصدر بيانات تغيير. لا يتوفّر التفعيل التلقائي لمصدر بيانات التغيير عند إنشاء مجموعة أو قاعدة بيانات.
لإنشاء مصدر بيانات تغيير، استخدِم Google Cloud Console.
-
في Google Cloud Console، انتقِل إلى صفحة قواعد البيانات.
- من القائمة، اختَر قاعدة بيانات Firestore متوافقة مع MongoDB. تفتح لوحة Firestore Studio.
- في لوحة المستكشف ، ابحث عن العقدة تغيير مصادر البيانات ، وانقر على إجراءات إضافية ، ثم انقر على إنشاء مصدر بيانات تغيير.
- أدخِل اسمًا فريدًا لمصدر بيانات التغيير ونطاقه ومدة الاحتفاظ به، ثم انقر على حفظ.
عرض مصادر بيانات التغييرات
يمكنك عرض تفاصيل حول مصادر بيانات التغييرات في Google Cloud Console.
-
في Google Cloud Console، انتقِل إلى صفحة قواعد البيانات.
- من القائمة، اختَر قاعدة بيانات Firestore متوافقة مع MongoDB. تفتح لوحة Firestore Studio.
- في لوحة المستكشف ، ابحث عن العقدة تغيير مصادر البيانات.
- لفتح العقدة أو إغلاقها، انقر على تبديل العقدة.
حذف مصدر بيانات تغيير
لحذف مصدر بيانات تغيير، استخدِم Google Cloud Console.
-
في Google Cloud Console، انتقِل إلى صفحة قواعد البيانات.
- من القائمة، اختَر قاعدة بيانات Firestore متوافقة مع MongoDB. تفتح لوحة Firestore Studio.
- في لوحة المستكشف ، ابحث عن العقدة تغيير مصادر البيانات.
- لفتح العقدة أو إغلاقها، انقر على تبديل العقدة.
- في المستكشف ، حدِّد مصدر بيانات التغيير الذي تريد حذفه.
- انقر على إجراءات إضافية و بعد ذلك، اختَر حذف مصدر بيانات تغيير.
- في مربّع الحوار، أدخِل اسم مصدر بيانات التغيير لتأكيد الحذف، ثم انقر على حذف.
فتح مؤشر مصدر بيانات تغيير أو استئنافه
توضّح الأمثلة التالية كيفية إنشاء مؤشر مصدر بيانات تغيير واستئنافه وضبطه.
قبل إنشاء مؤشر مصدر بيانات تغيير، عليك إنشاء مصدر بيانات تغيير بشكل صريح لقاعدة البيانات أو المجموعة.
إنشاء مؤشر مصدر بيانات تغيير
لإنشاء مؤشر مصدر بيانات تغيير جديد، استخدِم طريقة watch في برامج تشغيل MongoDB.
للاستماع إلى جميع التغييرات في قاعدة بيانات، أنشئ مصدر بيانات تغيير على مستوى قاعدة البيانات واستدعِ طريقة watch على العنصر db.
let cursor = db.watch()
لإنشاء مؤشر نطاقه مجموعة، عليك أولاً إنشاء مصدر بيانات تغيير لهذه المجموعة. بعد ذلك، استدعِ طريقة watch على المجموعة المقابلة.
let cursor = db.my_collection.watch()
بعد إنشاء مؤشر مصدر بيانات تغيير، يمكنك البدء في البث.
على سبيل المثال، إذا أدرجت مستندًا واستدعيت tryNext على المؤشر، سيظهر التغيير في مصدر بيانات التغيير.
let doc = db.my_collection.insertOne({value: "hello world"}) console.log(cursor.tryNext())
إذا عدّلت المستند وحذفته، ستظهر هذه التغييرات في مصدر بيانات التغيير:
db.my_collection.updateOne({"_id": doc.insertedId}, {$set: {value: "hello world!"}}) db.my_collection.deleteOne({"_id": doc.insertedId}}) // Prints the update event console.log(cursor.tryNext()) // Prints the delete event console.log(cursor.tryNext())
استئناف مصدر بيانات تغيير
لاستئناف مصدر بيانات تغيير، استخدِم الخيارَين resumeAfter أو startAfter.
لتحديد الموضع في سجلّ التغييرات الذي تريد الاستئناف منه باستخدام resumeAfter وstartAfter، استخدِم رمز استئناف.
// Create a cursor and add one event to the change stream. let cursor = db.my_collection.watch(); db.my_collection.insertOne({value: "hello world"}); let event = cursor.tryNext(); // Get the resume token from the event. let resumeToken = event._id; // Add a new event to the change stream. db.my_collection.insertOne({value: "foobar"}); // Create a new cursor by using the resume token as a starting point. let newCursor = db.my_collection.watch({resumeAfter: resumeToken}) // Log the change event containing the "foobar" value. console.log(newCursor.tryNext())
لاستخدام startAfter:
// Start after the resume token. let startAfterCursor = db.my_collection.watch({startAfter: resumeToken})
تضمين الصور المسبقة واللاحقة في عمليات التعديل والحذف
إذا لزم الأمر، يمكنك تضمين الصور المسبقة واللاحقة للمستندات في أحداث تغيير التعديل والحذف. تخضع إمكانية توفّر الصور لفترة "الاسترداد في نقطة زمنية" (PITR)، و للقراءة من صور المستندات التي يزيد عمرها عن ساعة واحدة، عليك تفعيل ميزة PITR.
تستفيد ميزة "تغيير مصادر البيانات" من فترة PITR لتقديم عرض للمستند قبل حدث التغيير المحدّد وبعده. تحتوي أحداث التعديل تلقائيًا على حقل updateDescription وهو الفرق بين الحقول التي تم تعديلها من خلال عملية التعديل.
لتضمين الصور المسبقة واللاحقة في حدث تغيير،
عليك
تحديد الخيارَين fullDocumentBeforeChange وfullDocument في طلب مصدر بيانات التغيير.
let cursor = db.my_collection.watch({ "fullDocument": "required", "fullDocumentBeforeChange": "required" })
إذا حاول طلب البحث قراءة مستند خارج فترة الاحتفاظ بميزة PITR أو إذا لم يتم تفعيل ميزة PITR، يعرض الخيار required رسالة خطأ من جهة الخادم.
كبديل لعرض خطأ، يمكنك استخدام القيمة whenAvailable لعرض قيمة null إذا لم تعُد الصور متاحة.
let cursor = db.my_collection.watch({ "fullDocument": "whenAvailable", "fullDocumentBeforeChange": "whenAvailable" })
تضمين الصورة الحالية في التعديلات
تحتوي أحداث التعديل تلقائيًا على حقل updateDescription وهو الفرق بين الحقول التي تم تعديلها من خلال عملية التعديل. بدلاً من ذلك، للبحث عن أحدث إصدار من المستند بأكمله، استخدِم القيمة updateLookup في الخيار fullDocument.
لا تتطلب هذه الميزة ميزة PITR وتُجري عملية بحث عن المستند.
let cursor = db.my_collection.watch({ "fullDocument": "updateLookup", })
عمليات القراءة المتوازية
لزيادة معدّل النقل، يمكنك استخدام الخيار firestoreWorkerConfig لتقسيم طلب مصدر بيانات تغيير على عدة برامج عاملة. يكون كل برنامج عامل مسؤولاً عن عرض التغييرات لمجموعة مختلفة من المستندات. عليك إنشاء مؤشر متوازٍ من خلال طلب runCommand أو aggregate.
على سبيل المثال، يمكنك توزيع مصدر بيانات تغيير على 3 برامج عاملة على النحو التالي:
let cursor1 = db.my_collection.aggregate([{ "$changeStream": { "firestoreWorkerConfig": {numWorkers: 3, workerId: 0 }} }]); let cursor2 = db.my_collection.aggregate([{ "$changeStream": { "firestoreWorkerConfig": {numWorkers: 3, workerId: 1 }} }]); let cursor3 = db.my_collection.aggregate([{ "$changeStream": { "firestoreWorkerConfig": {numWorkers: 3, workerId: 2 }} }]);
تغيير مصادر البيانات والنسخ الاحتياطية
لا يتوفّر إعداد مصدر بيانات التغيير ولا بيانات مصدر بيانات التغيير في عمليات استعادة النسخ الاحتياطية. إذا استعدت قاعدة بيانات تتضمّن ميزة "تغيير مصادر البيانات"، عليك إعادة إنشاء مصادر بيانات التغيير هذه في قاعدة البيانات الوجهة لفتح المؤشرات في قاعدة البيانات هذه.
الفوترة
- تتكبّد ميزة "تغيير مصادر البيانات" وحدات قراءة وتكاليف تخزين. يمكنك الاطّلاع على أسعار ميزة "تغيير مصادر البيانات".
- لتضمين الصور المسبقة واللاحقة التي يزيد عمرها عن ساعة واحدة في وقت طلب القراءة، عليك تفعيل ميزة PITR التي تتكبّد تكاليف PITR.
الاختلافات في السلوك
يصف القسم التالي الاختلافات في ميزة "تغيير مصادر البيانات" بين Firestore المتوافقة مع MongoDB وMongoDB.
updateDescription
updateDescription هو مستند في حدث update يصف الحقول
التي تم تعديلها أو إزالتها من خلال عملية التعديل. في
Cloud Firestore، تتمثّل الاختلافات البارزة في ما يلي:
- في
updateDescription، لا تتم تعبئة الحقلَينtruncatedArraysوdisambiguatedPaths. - يمثّل
updateDescription.updatedFieldsفرقًا أساسيًا بين الصور المسبقة واللاحقة لمستند قبل تطبيق عملية تغيير وبعدها.
إليك الحالة الأولية لمستند:
db.my_collection.insertOne({ _id: 1, root: { array: [{a: 1}, {b: 2}, {c: 3}] } })
السيناريو 1: تغيير العنصر الأول فقط من المصفوفة
في هذا السيناريو، يتطابق سلوك Cloud Firestore مع MongoDB.
db.my_collection.updateOne( {_id: 1}, {'$set': {"root.array.0.a": 100}} ) { updatedFields: {"root.array.0.a": 100}, removedFields: [] }
السيناريو 2: الكتابة فوق مصفوفة كاملة
في هذا السيناريو، لا تُعدِّل العملية سوى حقل المصفوفة الأول، ولكنها تكتب فوق المصفوفة بأكملها.
لا يميّز فرق التعديل في Cloud Firestore بين هذين
السيناريوهَين ويعرض updateDescription.updatedFields نفسه لكليهما:
db.my_collection.updateOne( {_id: 1}, {'$set': {"root.array": [{a: 100}, {b: 2}, {c: 3}]}} ) // In other implementations, updatedFields reflects the mutation itself { updatedFields: { "root.array": [{a: 100}, {b: 2}, {c: 3}] }, removedFields: [] } // Firestore updatedFields is the diff between the before and after versions of the document { updatedFields: {"root.array.0.a": 100}, removedFields: [] }