बदलावों की स्ट्रीम की मदद से रीयल-टाइम डेटा पढ़ना

MongoDB के साथ काम करने वाली Firestore की चेंज स्ट्रीम की सुविधा की मदद से, ऐप्लिकेशन को किसी कलेक्शन या पूरे डेटाबेस में किए गए बदलावों (डेटा डालना, अपडेट करना, और मिटाना) को रीयल-टाइम में ऐक्सेस करने की सुविधा मिलती है. बदलाव की स्ट्रीम, बदलाव के समय के हिसाब से अपडेट को क्रम में लगाती है.

MongoDB के साथ काम करने वाले एपीआई और MongoDB के पुराने ड्राइवर की मदद से, Change Streams को ऐक्सेस किया जा सकता है. Firestore के साथ काम करने वाले MongoDB में, Change Streams को लागू करने की सुविधा उपलब्ध है. इसकी मदद से, राइट और रीड के किसी भी थ्रूपुट को मैनेज किया जा सकता है. इसके लिए, राइट और रीड के पैरललिज़्म पर अपने-आप पार्टीशन करने की सुविधा को यूनीक तरीके से लागू किया जाता है. इससे ज़्यादा थ्रूपुट वाले वर्कलोड बनाए जा सकते हैं. Cloud Firestore और अन्य स्टोरेज समाधानों के बीच माइग्रेशन और डेटा सिंक्रनाइज़ेशन के इंफ़्रास्ट्रक्चर को भी बेहतर बनाया जा सकता है.

MongoDB ड्राइवर के साथ काम करने के अलावा, Cloud Firestore का इस्तेमाल करके, एक साथ कई बदलावों को पढ़ा जा सकता है. इससे आपको पैरलल और हाई-थ्रूपुट रीड वर्कलोड बनाने में मदद मिलती है. हर स्ट्रीम, नतीजों के अच्छी तरह से डिस्ट्रिब्यूट किए गए पार्टीशन को दिखाती है.

बदलावों के स्ट्रीम किए गए डेटा में ये सुविधाएं काम करती हैं:

  • डेटाबेस या कलेक्शन के स्कोप के साथ कॉन्फ़िगर की जा सकने वाली चेंज स्ट्रीम.
  • बदलाव की स्ट्रीम के लिए रखरखाव की अवधि, जिसे स्ट्रीम बनाते समय तय किया जाता है. डिफ़ॉल्ट रूप से, डेटा को 7 दिनों तक सेव करके रखा जाता है. हालांकि, इसे कम से कम 1 दिन तक सेव करके रखा जा सकता है. डेटा बनाए रखने की अवधि, एक दिन के हिसाब से तय की जाती है. यह अवधि ज़्यादा से ज़्यादा सात दिन हो सकती है. निजी डेटा के रखरखाव की अवधि में बदलाव नहीं किया जा सकता. डेटा बनाए रखने की अवधि में बदलाव करने के लिए, आपको बदलाव की स्ट्रीम को हटाकर फिर से बनाना होगा.
  • delete, insert, update, और drop में बदलाव से जुड़े इवेंट, जिन्हें db.collection.watch() और db.watch() का इस्तेमाल करके देखा जा सकता है.
  • updateDescription.updatedFields में अपडेट के अंतर शामिल हैं.
  • सभी fullDocument और fullDocumentBeforeChange विकल्प.
    • अपडेट के लिए पूरा दस्तावेज़ देखा जा रहा है.
    • दस्तावेज़ की वह इमेज जो उसे बदलने, अपडेट करने या मिटाने से पहले की थी.
    • दस्तावेज़ को बदलने या अपडेट करने के बाद की इमेज.
    • एक घंटे से ज़्यादा पुरानी प्री और पोस्ट इमेज के लिए, पॉइंट-इन-टाइम रिकवरी (पीआईटीआर) की सुविधा चालू करनी होगी.
  • फिर से शुरू करने के सभी विकल्प, जिनमें resumeAfter और startAfter शामिल हैं.
  • बदलावों को मॉनिटर करने के लिए watch() का इस्तेमाल करते समय, एग्रीगेशन स्टेज को एक साथ इस्तेमाल किया जा सकता है. जैसे, $addFields, $match, $project, $replaceRoot, $replaceWith, $set, और $unset.

बदलावों की स्ट्रीम कॉन्फ़िगर करना

किसी डेटाबेस के लिए, बदलावों की स्ट्रीम बनाने, हटाने या देखने के लिए, Google Cloud Console का इस्तेमाल करें.

भूमिकाएं और अनुमतियां

बदलावों की स्ट्रीम बनाने, मिटाने, और उनकी सूची बनाने के लिए, किसी प्रिंसिपल के पास datastore.schemas.create, datastore.schemas.delete, और datastore.schemas.list पहचान और ऐक्सेस मैनेजमेंट (आईएएम) अनुमतियां होनी चाहिए.

उदाहरण के लिए, Datastore इंडेक्स एडमिन (roles/datastore.indexAdmin) की भूमिका से ये अनुमतियां मिलती हैं.

बदलाव की स्ट्रीम बनाना

बदलाव की स्ट्रीम के कर्सर को खोलने से पहले, आपको बदलाव की स्ट्रीम बनानी होगी. कलेक्शन या डेटाबेस बनाते समय, बदलावों को स्ट्रीम करने की सुविधा अपने-आप चालू नहीं होती.

बदलाव की स्ट्रीम बनाने के लिए, Google Cloud Console का इस्तेमाल करें.

  1. Google Cloud Console में, डेटाबेस पेज पर जाएं.

    डेटाबेस पर जाएं

  2. सूची में से, MongoDB के साथ काम करने वाला कोई Firestore डेटाबेस चुनें. Firestore Studio पैनल खुलता है.
  3. एक्सप्लोरर पैनल में, बदलाव की स्ट्रीम नोड ढूंढें. इसके बाद, ज़्यादा कार्रवाइयां पर क्लिक करें. इसके बाद, बदलाव की स्ट्रीम बनाएं चुनें.
  4. बदलाव की स्ट्रीम का कोई यूनीक नाम, स्कोप, और डेटा बनाए रखने की अवधि डालें. इसके बाद, सेव करें पर क्लिक करें

बदलाव की स्ट्रीम देखना

Google Cloud Console में, बदलावों के स्ट्रीम की जानकारी देखी जा सकती है.

  1. Google Cloud Console में, डेटाबेस पेज पर जाएं.

    डेटाबेस पर जाएं

  2. सूची में से, MongoDB के साथ काम करने वाला कोई Firestore डेटाबेस चुनें. Firestore Studio पैनल खुलता है.
  3. एक्सप्लोरर पैनल में, बदलावों की स्ट्रीम नोड ढूंढें.
  4. नोड को खोलने या बंद करने के लिए, नोड टॉगल करें पर क्लिक करें.

बदलावों की स्ट्रीम मिटाना

बदलावों की स्ट्रीम मिटाने के लिए, Google Cloud Console का इस्तेमाल करें.

  1. Google Cloud Console में, डेटाबेस पेज पर जाएं.

    डेटाबेस पर जाएं

  2. सूची में से, MongoDB के साथ काम करने वाला कोई Firestore डेटाबेस चुनें. Firestore Studio पैनल खुलता है.
  3. एक्सप्लोरर पैनल में, बदलावों की स्ट्रीम नोड ढूंढें.
  4. नोड को खोलने या बंद करने के लिए, नोड टॉगल करें पर क्लिक करें.
  5. एक्सप्लोरर में जाकर, वह बदलाव स्ट्रीम ढूंढें जिसे मिटाना है.
  6. ज़्यादा कार्रवाइयां पर क्लिक करें. इसके बाद, बदलाव स्ट्रीम मिटाएं को चुनें.
  7. डायलॉग बॉक्स में, बदलाव की स्ट्रीम का नाम डालें, ताकि यह पुष्टि की जा सके कि आपको इसे मिटाना है. इसके बाद, मिटाएं पर क्लिक करें.

बदलाव की स्ट्रीम के कर्सर को खोलना या फिर से शुरू करना

यहां दिए गए उदाहरणों में, बदलावों के स्ट्रीम कर्सर को बनाने, फिर से शुरू करने, और कॉन्फ़िगर करने का तरीका बताया गया है.

बदलाव की स्ट्रीम का कर्सर बनाने से पहले, आपको डेटाबेस या कलेक्शन के लिए बदलाव की स्ट्रीम बनानी होगी.

बदलाव की स्ट्रीम का कर्सर बनाना

नई बदलाव स्ट्रीम का कर्सर बनाने के लिए, MongoDB ड्राइवर में watch तरीके का इस्तेमाल करें. डेटाबेस में हुए सभी बदलावों को सुनने के लिए, डेटाबेस के स्कोप वाली बदलाव स्ट्रीम बनाएं. इसके बाद, watch ऑब्जेक्ट पर 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 विंडो का इस्तेमाल करके, बदलाव से पहले और बाद के दस्तावेज़ का व्यू दिखाती हैं. डिफ़ॉल्ट रूप से, अपडेट इवेंट में एक 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 फ़ील्ड होता है. यह अपडेट ऑपरेशन से बदले गए फ़ील्ड का डेल्टा होता है. पूरे दस्तावेज़ के सबसे नए वर्शन को देखने के लिए, fullDocument विकल्प में मौजूद updateLookup वैल्यू का इस्तेमाल करें.

इस सुविधा के लिए, PITR की ज़रूरत नहीं होती. यह दस्तावेज़ को ढूंढती है.

let cursor = db.my_collection.watch({
  "fullDocument": "updateLookup",
})

पैरलल रीड

थ्रूपुट बढ़ाने के लिए, firestoreWorkerConfig विकल्प का इस्तेमाल किया जा सकता है. इससे बदलावों की स्ट्रीम वाली क्वेरी को कई वर्कर में बांटा जा सकता है. हर वर्कर, दस्तावेज़ों के अलग-अलग सेट में बदलाव करने के लिए ज़िम्मेदार होता है. आपको runCommand या aggregate क्वेरी के ज़रिए, पैरलल कर्सर बनाना होगा.

उदाहरण के लिए, बदलावों के स्ट्रीम को तीन वर्कर में इस तरह बांटा जा सकता है:

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 }}
  }]);

स्ट्रीम और बैकअप बदलना

बैकअप को वापस लाने की प्रोसेस में, न तो बदलावों की स्ट्रीम का कॉन्फ़िगरेशन और न ही बदलावों की स्ट्रीम का डेटा उपलब्ध होता है. अगर आपको बदलावों की स्ट्रीम वाला डेटाबेस वापस लाना है, तो आपको डेस्टिनेशन डेटाबेस में उन बदलावों की स्ट्रीम को फिर से बनाना होगा, ताकि उस डेटाबेस के कर्सर खोले जा सकें.

बिलिंग

व्यवहार में अंतर

यहां दिए गए सेक्शन में, MongoDB के साथ काम करने वाले Firestore और 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}]
  }
})

पहला उदाहरण: सिर्फ़ ऐरे के पहले एलिमेंट में बदलाव करना.

इस उदाहरण में, Cloud Firestore का व्यवहार MongoDB से मेल खाता है.

db.my_collection.updateOne(
  {_id: 1},
  {'$set': {"root.array.0.a": 100}}
)

{
  updatedFields: {"root.array.0.a": 100},
  removedFields: []
}

दूसरी स्थिति: पूरे कलेक्शन को फिर से लिखना

इस स्थिति में, ऑपरेशन सिर्फ़ पहले ऐरे फ़ील्ड को अपडेट करता है. हालाँकि, यह पूरी ऐरे को बदल देता है.

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: []
}

आगे क्या करना है