Değişiklik akışlarıyla gerçek zamanlı verileri okuma

MongoDB uyumlu Firestore için Değişiklik Akışları, uygulamaların bir koleksiyonda veya veritabanının tamamında yapılan anlık değişikliklere (ekleme, güncelleme ve silme) erişmesine olanak tanır. Değişiklik akışı, güncellemeleri değişiklik zamanına göre sıralar.

Değişiklik akışlarına, MongoDB uyumlu API'ler ve geleneksel MongoDB sürücüleri aracılığıyla erişilebilir. MongoDB uyumlu Firestore'un Değişiklik Akışları uygulaması, yazma ve okuma paralelliği üzerinde otomatik bölümlemenin benzersiz bir uygulaması aracılığıyla her türlü yazma ve okuma işleme kapasitesini yönetebilir. Bu sayede yüksek gönderim hacimli iş yükleri oluşturabilirsiniz. Ayrıca, Cloud Firestore ile diğer depolama çözümleri arasındaki taşıma ve veri senkronizasyonu altyapısını iyileştirebilirsiniz.

MongoDB sürücüleriyle uyumluluğun yanı sıra değişiklik akışlarını paralel olarak okumak için Cloud Firestore kullanabilirsiniz. Bu sayede paralel, yüksek gönderim hacimli okuma iş yükleri oluşturabilirsiniz. Her akış, sonuçların iyi dağıtılmış bir bölümünü temsil eder.

Değişiklik akışları aşağıdaki özellikleri destekler:

  • Veritabanı veya koleksiyon kapsamına sahip yapılandırılabilir değişiklik akışları.
  • Oluşturma sırasında belirtilen bir değişiklik akışının saklama süresi. Varsayılan saklama süresi 7 gün, minimum saklama süresi ise 1 gündür. Saklama süresi, 1 günün katı olmalı ve en fazla 7 gün olmalıdır. Saklama süresi, oluşturma işleminden sonra değiştirilemez. Saklama süresini değiştirmek için değişiklik akışını silip yeniden oluşturmanız gerekir.
  • delete, insert, update ve drop, db.collection.watch() ve db.watch() kullanılarak gözlemlenebilen değişiklik etkinlikleridir.
  • updateDescription.updatedFields, güncelleme farklarını içerir.
  • Tüm fullDocument ve fullDocumentBeforeChange seçenekleri.
    • Güncellemeler için belgenin tamamı inceleniyor.
    • Değiştirilmeden, güncellenmeden veya silinmeden önce dokümanın ön görüntüsü.
    • Değiştirildikten veya güncellendikten sonra dokümanın son görüntüsü.
    • Bir saatten eski olan önceki ve sonraki görüntüler için belirli bir noktadan önceyi kurtarma (PITR) özelliğinin etkinleştirilmesi gerekir.
  • resumeAfter ve startAfter dahil tüm devam ettirme seçenekleri.
  • Değişiklikleri gözlemlemek için watch() kullanırken $addFields, $match, $project, $replaceRoot, $replaceWith, $set ve $unset gibi toplama aşamalarını zincirleyebilirsiniz.

Değişiklik akışlarını yapılandırma

Bir veritabanı için değişiklik akışları oluşturmak, silmek veya mevcut değişiklik akışlarını görüntülemek için Google Cloud Console'u kullanın.

Roller ve izinler

Değişiklik akışları oluşturmak, silmek ve listelemek için bir alt öğenin sırasıyla datastore.schemas.create, datastore.schemas.delete ve datastore.schemas.list Identity and Access Management (IAM) izinlerine sahip olması gerekir.

Örneğin, veri deposu dizini Yöneticisi (roles/datastore.indexAdmin) rolü bu izinleri verir.

Değişiklik akışı oluşturma

İlgili değişiklik akışı imlecini açabilmeniz için önce bir değişiklik akışı oluşturmanız gerekir. Koleksiyon veya veritabanı oluşturma sırasında otomatik değişiklik akışı etkinleştirme desteklenmez.

Değişiklik akışı oluşturmak için Google Cloud Console'u kullanın.

  1. Google Cloud Console'da Veritabanları sayfasına gidin.

    Veritabanları'na gidin

  2. Listeden MongoDB uyumlu bir Firestore veritabanı seçin. Firestore Studio paneli açılır.
  3. Explorer panelinde Change streams (Değişiklik akışları) düğümünü bulun, More actions'ı (Diğer işlemler) tıklayın ve ardından Create change stream'i (Değişiklik akışı oluştur) seçin.
  4. Benzersiz bir değişiklik akışı adı, kapsam ve saklama süresi girip Kaydet'i tıklayın.

Değişiklik akışlarını görüntüleme

Değişiklik akışlarıyla ilgili ayrıntıları Google Cloud Console'da görüntüleyebilirsiniz.

  1. Google Cloud Console'da Veritabanları sayfasına gidin.

    Veritabanları'na gidin

  2. Listeden MongoDB uyumlu bir Firestore veritabanı seçin. Firestore Studio paneli açılır.
  3. Explorer panelinde Change streams (Değişiklik akışları) düğümünü bulun.
  4. Düğümü açmak veya kapatmak için Düğümü aç/kapat'ı tıklayın.

Değişiklik akışını silme

Değişiklik akışını silmek için Google Cloud Console'u kullanın.

  1. Google Cloud Console'da Veritabanları sayfasına gidin.

    Veritabanları'na gidin

  2. Listeden MongoDB uyumlu bir Firestore veritabanı seçin. Firestore Studio paneli açılır.
  3. Explorer panelinde Change streams (Değişiklik akışları) düğümünü bulun.
  4. Düğümü açmak veya kapatmak için Düğümü aç/kapat'ı tıklayın.
  5. Gezgin'de silmek istediğiniz değişiklik akışını bulun.
  6. Diğer işlemler'i tıklayın ve ardından Değişiklik akışını sil'i seçin.
  7. İletişim kutusunda, silme işlemini onaylamak için değişiklik akışının adını girin ve ardından Sil'i tıklayın.

Değişiklik akışı imlecini açma veya devam ettirme

Aşağıdaki örneklerde, değişiklik akışı imlecinin nasıl oluşturulacağı, devam ettirileceği ve yapılandırılacağı gösterilmektedir.

Değişiklik akışı imleci oluşturmadan önce veritabanı veya koleksiyon için açıkça değişiklik akışı oluşturmanız gerekir.

Değişiklik akışı imleci oluşturma

Yeni bir değişiklik akışı imleci oluşturmak için MongoDB sürücülerindeki watch yöntemini kullanın. Bir veritabanındaki tüm değişiklikleri dinlemek için veritabanı kapsamlı bir değişiklik akışı oluşturun ve db nesnesinde watch yöntemini çağırın.

let cursor = db.watch()

Kapsamı bir koleksiyon olan imleç oluşturmak için önce o koleksiyon için bir değişiklik akışı oluşturmanız gerekir. Ardından, ilgili koleksiyonda watch yöntemini çağırın.

let cursor = db.my_collection.watch()

Değişiklik akışı imlecini oluşturduğunuza göre akışa başlayabilirsiniz. Örneğin, bir doküman ekleyip imleçte tryNext yöntemini çağırırsanız değişikliğin değişiklik akışında göründüğünü görürsünüz.

let doc = db.my_collection.insertOne({value: "hello world"})
console.log(cursor.tryNext())

Dokümanı güncelleyip silerseniz bu değişikliklerin değişiklik akışında göründüğünü görürsünüz:

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())

Değişiklik akışını devam ettirme

Değişiklik akışını devam ettirmek için resumeAfter veya startAfter seçeneklerini kullanın. Değişiklik günlüğünde resumeAfter ve startAfter'den nereden devam edileceğini belirlemek için devam jetonu kullanın.

// 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 uygulamasını kullanmak için:

// Start after the resume token.
let startAfterCursor = db.my_collection.watch({startAfter: resumeToken})

Güncellemelere öncesi ve sonrası resimlerini ekleme ve silme

Gerekirse güncelleme ve silme değişiklik etkinliklerine belgelerin önceki ve sonraki resimlerini ekleyebilirsiniz. Resimlerin kullanılabilirliği belirli bir noktadan önceyi kurtarma (PITR) penceresine tabidir. Bir saatten eski doküman resimlerini okumak için PITR'yi etkinleştirmeniz gerekir.

Değişiklik akışları, belirli bir değişiklik etkinliğinden önce ve sonra belgenin görünümünü sağlamak için PITR aralığından yararlanır. Varsayılan olarak güncelleme etkinlikleri, güncelleme işlemi tarafından değiştirilen alanların farkı olan bir updateDescription alanı içerir.

Değişiklik etkinliğine önceki ve sonraki resimleri dahil etmek için değişiklik akışı sorgusunda fullDocumentBeforeChange ve fullDocument seçeneklerini belirtmeniz gerekir.

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

Sorgu, PITR saklama penceresinin dışındaki bir dokümanı okumaya çalışırsa veya PITR etkinleştirilmemişse required değeri, sunucu tarafı hata mesajı döndürür.

Hata oluşturmak yerine, resimler artık mevcut değilse null değeri döndürmek için whenAvailable değerini kullanabilirsiniz.

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

Mevcut resmi güncellemelere dahil etme

Varsayılan olarak, güncelleme etkinlikleri, güncelleme işlemi tarafından değiştirilen alanların farkı olan bir updateDescription alanı içerir. Bunun yerine tüm dokümanın en güncel sürümünü aramak için fullDocument seçeneğindeki updateLookup değerini kullanın.

Bu özellik, PITR gerektirmez ve doküman için arama yapar.

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

Paralel Okuma

İşleme hızını artırmak için firestoreWorkerConfig seçeneğini kullanarak değişiklik akışı sorgusunu birden fazla çalışana bölebilirsiniz. Her çalışan, farklı bir doküman grubundaki değişiklikleri sunmaktan sorumludur. runCommand veya aggregate sorgusu aracılığıyla paralel imleç oluşturmanız gerekir.

Örneğin, bir değişiklik akışını 3 çalışan arasında şu şekilde dağıtabilirsiniz:

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

Değişiklik akışları ve yedekler

Yedekleme geri yükleme işlemlerinde değişiklik akışı yapılandırması da değişiklik akışı verileri de kullanılamaz. Değişiklik akışları içeren bir veritabanını geri yüklerseniz bu veritabanında imleç açmak için hedef veritabanında bu değişiklik akışlarını yeniden oluşturmanız gerekir.

Faturalandırma

Davranış farklılıkları

Aşağıdaki bölümde, MongoDB uyumlu Firestore ile MongoDB arasındaki değişiklik akışları farkları açıklanmaktadır.

updateDescription

updateDescription, güncelleme işlemi tarafından güncellenen veya kaldırılan alanları açıklayan bir update etkinliğindeki belgedir. Cloud Firestore'da dikkate değer farklar şunlardır:

  • updateDescription tablosunda truncatedArrays ve disambiguatedPaths alanları doldurulmaz.
  • updateDescription.updatedFields, bir mutasyon uygulanmadan önce ve sonra bir dokümanın öncesi ve sonrası resimleri arasındaki standart farkı temsil eder.

Bir dokümanın aşağıdaki ilk durumunu ele alalım:

db.my_collection.insertOne({
  _id: 1,
  root: {
    array: [{a: 1}, {b: 2}, {c: 3}]
  }
})

1. senaryo: Yalnızca dizinin ilk öğesini değiştirme.

Bu senaryoda Cloud Firestore davranışı MongoDB ile eşleşir.

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

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

Senaryo 2: Tüm dizinin üzerine yazma

Bu senaryoda işlem yalnızca ilk dizi alanını günceller ancak tüm dizinin üzerine yazar.

Cloud Firestore güncelleme farkı, bu iki senaryo arasında ayrım yapmaz ve her ikisi için de aynı updateDescription.updatedFields değerini döndürür:

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

Sırada ne var?