Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
Menu Docs

Monitorar alterações de dados

Neste guia, você pode aprender como usar um fluxo de alterações para monitorar alterações em tempo real em seus dados. Um change stream é uma funcionalidade do MongoDB Server que permite que seu aplicação se inscreva em alterações de dados em uma collection, banco de dados de dados ou sistema.

Dica

Atlas Stream Processing

Como uma alternativa para alterar fluxos, você pode utilizar o Atlas Stream Processing para processar e transformar fluxos de dados. Ao contrário dos change streams, que registram apenas eventos de banco de dados, o Atlas Stream Processing gerencia vários tipos de evento de dados e fornece funcionalidades estendidas de processamento de dados. Para saber mais sobre esse recurso, consulte Atlas Stream Processing na documentação do MongoDB Atlas.

Os exemplos neste guia usam a collection sample_restaurants.restaurants dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de amostra, consulte a Introdução ao driver .NET/C#.

Os exemplos desta página utilizam as seguintes classes Restaurant, Address e GradeEntry como modelos:

public class Restaurant
{
public ObjectId Id { get; set; }
public string Name { get; set; }
[BsonElement("restaurant_id")]
public string RestaurantId { get; set; }
public string Cuisine { get; set; }
public Address Address { get; set; }
public string Borough { get; set; }
public List<GradeEntry> Grades { get; set; }
}
public class Address
{
public string Building { get; set; }
[BsonElement("coord")]
public double[] Coordinates { get; set; }
public string Street { get; set; }
[BsonElement("zipcode")]
public string ZipCode { get; set; }
}
public class GradeEntry
{
public DateTime Date { get; set; }
public string Grade { get; set; }
public float? Score { get; set; }
}

Observação

Os documentos na collection restaurants usam a convenção de nomenclatura snake-case. Os exemplos neste guia usam um ConventionPack para desserializar os campos na coleção em maiúsculas e minúsculas Pascal e mapeá-los para as propriedades na classe Restaurant .

Para saber mais sobre serialização personalizada, consulte Serialização personalizada.

Para abrir um change stream, chame o método Watch() ou WatchAsync() . A instância na qual você chama o método determina o escopo de eventos que o change stream escuta. Você pode chamar o método Watch() ou WatchAsync() nas seguintes classes:

  • MongoClient: Para monitorar todas as alterações no sistema MongoDB

  • Database: Para monitorar alterações em todas as coleções no banco de dados

  • Collection: Para monitorar alterações na coleção

O exemplo a seguir abre um fluxo de alteração na coleção restaurants e gera as alterações conforme elas ocorrem. Selecione a aba Synchronous ou Asynchronous para ver o código correspondente.

var database = client.GetDatabase("sample_restaurants");
var collection = database.GetCollection<Restaurant>("restaurants");
// Opens a change stream and prints the changes as they're received
using (var cursor = collection.Watch())
{
foreach (var change in cursor.ToEnumerable())
{
Console.WriteLine("Received the following type of change: " + change.BackingDocument);
}
}
var database = client.GetDatabase("sample_restaurants");
var collection = database.GetCollection<Restaurant>("restaurants");
// Opens a change streams and print the changes as they're received
using var cursor = await collection.WatchAsync();
await cursor.ForEachAsync(change =>
{
Console.WriteLine("Received the following type of change: " + change.BackingDocument);
});

Para começar a observar as alterações, execute o aplicação. Em seguida, em um aplicação ou shell separado, modifique a coleção restaurants . Atualizar um documento que tenha um valor de resulta na seguinte saída do "name" "Blarney Castle" :

{ "_id" : { "_data" : "..." }, "operationType" : "update", "clusterTime" : Timestamp(...),
"wallTime" : ISODate("..."), "ns" : { "db" : "sample_restaurants", "coll" : "restaurants" },
"documentKey" : { "_id" : ObjectId("...") }, "updateDescription" : { "updatedFields" : { "cuisine" : "Irish" },
"removedFields" : [], "truncatedArrays" : [] } }

Você pode passar o parâmetro pipeline para os métodos Watch() e WatchAsync() para modificar a saída do change stream. Esse parâmetro permite que você observe somente eventos de alteração especificados. Crie o pipeline usando a classe EmptyPipelineDefinition e anexando os métodos relevantes do estágio de agregação .

Você pode especificar os seguintes estágios de agregação no parâmetro pipeline :

  • $addFields

  • $changeStreamSplitLargeEvent

  • $match

  • $project

  • $replaceRoot

  • $replaceWith

  • $redact

  • $set

  • $unset

Dica

Para saber como criar um agregação pipeline usando a classe PipelineDefinitionBuilder, consulte Estágios do aggregation pipeline no guia Operações com construtores.

Para saber mais sobre como modificar a saída do change stream, consulte a seção Modificar a saída do change stream no manual do MongoDB Server .

O exemplo a seguir usa o parâmetro pipeline para abrir um fluxo de alterações que registra somente operações de atualização. Selecione a aba Synchronous ou Asynchronous para ver o código correspondente.

var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Restaurant>>()
.Match(change => change.OperationType == ChangeStreamOperationType.Update);
// Opens a change streams and print the changes as they're received
using (var cursor = collection.Watch(pipeline))
{
foreach (var change in cursor.ToEnumerable())
{
Console.WriteLine("Received the following change: " + change);
}
}
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Restaurant>>()
.Match(change => change.OperationType == ChangeStreamOperationType.Update);
// Opens a change stream and prints the changes as they're received
using (var cursor = await collection.WatchAsync(pipeline))
{
await cursor.ForEachAsync(change =>
{
Console.WriteLine("Received the following change: " + change);
});
}

Se o seu aplicação gerar eventos de alteração que excedam 16 MB, o servidor retornará um erro BSONObjectTooLarge. Para evitar esse erro, você pode usar o estágio de pipeline $changeStreamSplitLargeEvent para divisão os eventos em fragmentos menores. A API de agregação do driver .NET /C# inclui o método ChangeStreamSplitLargeEvent(), que você pode usar para adicionar o estágio $changeStreamSplitLargeEvent ao pipeline do change stream.

Este exemplo instrui o driver a observar as alterações e divisão os eventos de alteração que excedam o limite de 16 MB. O código imprime o documento de alteração para cada evento e chama métodos assistente para reagrupar quaisquer fragmentos de evento :

var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Restaurant>>()
.ChangeStreamSplitLargeEvent();
using var cursor = collection.Watch(pipeline);
foreach (var completeEvent in GetNextChangeStreamEvent(cursor.ToEnumerable().GetEnumerator()))
{
Console.WriteLine("Received the following change: " + completeEvent.BackingDocument);
}
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Restaurant>>()
.ChangeStreamSplitLargeEvent();
using var cursor = await collection.WatchAsync(pipeline);
await foreach (var completeEvent in GetNextChangeStreamEventAsync(cursor))
{
Console.WriteLine("Received the following change: " + completeEvent.BackingDocument);
}

Observação

Recomendamos reagrupar fragmentos de evento de alteração, como mostrado no exemplo anterior, mas esta etapa é opcional. Você pode usar a mesma lógica para assistir a eventos de alteração divisão e completos.

O exemplo anterior utiliza os métodos GetNextChangeStreamEvent(), GetNextChangeStreamEventAsync() e MergeFragment() para reagrupar fragmentos de evento de alteração em um único change stream documento. O seguinte código define estes métodos:

// Fetches the next complete change stream event
private static IEnumerable<ChangeStreamDocument<TDocument>> GetNextChangeStreamEvent<TDocument>(
IEnumerator<ChangeStreamDocument<TDocument>> changeStreamEnumerator)
{
while (changeStreamEnumerator.MoveNext())
{
var changeStreamEvent = changeStreamEnumerator.Current;
if (changeStreamEvent.SplitEvent != null)
{
var fragment = changeStreamEvent;
while (fragment.SplitEvent.Fragment < fragment.SplitEvent.Of)
{
changeStreamEnumerator.MoveNext();
fragment = changeStreamEnumerator.Current;
MergeFragment(changeStreamEvent, fragment);
}
}
yield return changeStreamEvent;
}
}
// Merges a fragment into the base event
private static void MergeFragment<TDocument>(
ChangeStreamDocument<TDocument> changeStreamEvent,
ChangeStreamDocument<TDocument> fragment)
{
foreach (var element in fragment.BackingDocument)
{
if (element.Name != "_id" && element.Name != "splitEvent")
{
changeStreamEvent.BackingDocument[element.Name] = element.Value;
}
}
}
// Fetches the next complete change stream event
private static async IAsyncEnumerable<ChangeStreamDocument<TDocument>> GetNextChangeStreamEventAsync<TDocument>(
IAsyncCursor<ChangeStreamDocument<TDocument>> changeStreamCursor)
{
var changeStreamEnumerator = GetNextChangeStreamEventFragmentAsync(changeStreamCursor).GetAsyncEnumerator();
while (await changeStreamEnumerator.MoveNextAsync())
{
var changeStreamEvent = changeStreamEnumerator.Current;
if (changeStreamEvent.SplitEvent != null)
{
var fragment = changeStreamEvent;
while (fragment.SplitEvent.Fragment < fragment.SplitEvent.Of)
{
await changeStreamEnumerator.MoveNextAsync();
fragment = changeStreamEnumerator.Current;
MergeFragment(changeStreamEvent, fragment);
}
}
yield return changeStreamEvent;
}
}
private static async IAsyncEnumerable<ChangeStreamDocument<TDocument>> GetNextChangeStreamEventFragmentAsync<TDocument>(
IAsyncCursor<ChangeStreamDocument<TDocument>> changeStreamCursor)
{
while (await changeStreamCursor.MoveNextAsync())
{
foreach (var changeStreamEvent in changeStreamCursor.Current)
{
yield return changeStreamEvent;
}
}
}
// Merges a fragment into the base event
private static void MergeFragment<TDocument>(
ChangeStreamDocument<TDocument> changeStreamEvent,
ChangeStreamDocument<TDocument> fragment)
{
foreach (var element in fragment.BackingDocument)
{
if (element.Name != "_id" && element.Name != "splitEvent")
{
changeStreamEvent.BackingDocument[element.Name] = element.Value;
}
}
}

Dica

Para saber mais sobre a divisão de grandes eventos de alteração, consulte $changeStreamSplitLargeEvent no manual do MongoDB Server .

Os métodos Watch() e WatchAsync() aceitam parâmetros opcionais, que representam opções que você pode utilizar para configurar a operação. Se você não especificar nenhuma opção, o driver não personalizará a operação.

A tabela a seguir descreve as opções que você pode definir para personalizar o comportamento de Watch() e WatchAsync():

Opção
Descrição

FullDocument

Specifies whether to show the full document after the change, rather than showing only the changes made to the document. To learn more about this option, see Include Pre-Images and Post-Images.

FullDocumentBeforeChange

Specifies whether to show the full document as it was before the change, rather than showing only the changes made to the document. To learn more about this option, see Include Pre-Images and Post-Images.

ResumeAfter

Direciona Watch() ou WatchAsync() para retomar as alterações de retorno após a operação especificada no token de retomada.
Cada documento de evento de fluxo de alterações inclui um token de retomada como o campo _id. Passe todo o campo _id do documento do evento de alteração que representa a operação que você deseja retomar depois.
ResumeAfter é mutuamente exclusivo com StartAfter e StartAtOperationTime.

StartAfter

Direciona Watch() ou WatchAsync() para iniciar um novo fluxo de alterações após a operação especificada no token de retomada. Permite que as notificações sejam retomadas após um evento de invalidação.
Cada documento de evento de fluxo de alteração inclui um token de currículo como o campo _id. Passe todo o campo _id do documento do evento de alteração que representa a operação que você deseja retomar depois.
StartAfter é mutuamente exclusivo com ResumeAfter e StartAtOperationTime.

StartAtOperationTime

Direciona Watch() ou WatchAsync() para retornar apenas eventos que ocorrem após o registro de data/hora especificado.
StartAtOperationTime é mutuamente exclusivo com ResumeAfter e StartAfter.

MaxAwaitTime

Especifica a quantidade máxima de tempo, em milissegundos, o servidor aguarda novas alterações de dados para relatar ao cursor do fluxo de alterações antes de retornar um lote vazio. Padrão para 1000 milissegundos.

ShowExpandedEvents

A partir do MongoDB Server v6.0, Os fluxos de alterações oferecem suporte a notificações de alteração para eventos de Linguagem de Definição de Dados (DDL), como os eventos createIndexes e dropIndexes . Para incluir eventos expandidos em um fluxo de alteração, crie o cursor do fluxo de alteração e defina esse parâmetro como True.

batchSize

Especifica o número máximo de documentos que um fluxo de alterações pode retornar em cada lote, que se aplica a Watch() ou WatchAsync(). Se a opção batchSize não estiver definida, as funções de observação terão um tamanho de lote inicial de 101 documentos e um tamanho máximo de 16 mebibytes (MiB) para cada lote subsequente. Esta opção pode forçar um limite menor do que 16 MiB, mas não maior. Se você definir batchSize para um limite que resulte em lotes maiores que 16 MiB, esta opção não terá efeito e Watch() ou WatchAsync() usará o tamanho de lote padrão.

Collation

Especifica o agrupamento a ser usado para o cursor do change stream. Consulte a seção Agrupamento desta página para obter mais informações.

Comment

Anexa um comentário à operação.

Para configurar o agrupamento para sua operação, crie uma instância da classe Agrupamento.

A tabela seguinte descreve os parâmetros que o construtor do Collation aceita. Ela também lista a propriedade de classe correspondente que você pode usar para ler o valor de cada configuração.

Parâmetro
Descrição
Propriedade de classe

locale

Specifies the International Components for Unicode (ICU) locale. For a list of supported locales, see Collation Locales and Default Parameters in the MongoDB Server Manual.

If you want to use simple binary comparison, use the Collation.Simple static property to return a Collation object with the locale set to "simple".
Data Type: string

Locale

caseLevel

(Opcional) Especifica se a comparação de caso deve ser incluída.

Quando este argumento é true, o comportamento do driver depende do valor do argumento strength:

- Se strength for CollationStrength.Primary, o driver compara caracteres básicos e maiúsculas e minúsculas.
- Se strength for CollationStrength.Secondary, o driver compara caracteres básicos, diacríticos, outras diferenças secundárias e maiúsculas e minúsculas.
- Se strength for qualquer outro valor, este argumento será ignorado.

Quando este argumento é false, o driver não inclui comparação de maiúsculas e minúsculas no nível de força Primary ou Secondary.

Tipo de dados: boolean
Padrão: false

CaseLevel

caseFirst

(Optional) Specifies the sort order of case differences during tertiary level comparisons.

Data Type: CollationCaseFirst
Default: CollationCaseFirst.Off

CaseFirst

strength

(Optional) Specifies the level of comparison to perform, as defined in the ICU documentation.

Data Type: CollationStrength
Default: CollationStrength.Tertiary

Strength

numericOrdering

(Opcional) Especifica se o driver compara strings numéricas como números.

Se esse argumento true for, o driver compara strings numéricas como números. Por exemplo, ao comparar as strings "10" e "2", o driver trata os valores como 10 2e, e considera 10 maior.

Se esse argumento for false ou excluído, o driver compara cadeias de caracteres numéricas como cadeias de caracteres. Por exemplo, ao comparar as strings "10" e "2", o driver compara um caractere de cada vez. Porque "1" é inferior a "2", o condutor encontra "10" para ser menor que "2".

Para obter mais informações, consulte Restrições de agrupamento no manual do MongoDB Server .

Tipo de Dados: boolean
Padrão: false

NumericOrdering

alternate

(Optional) Specifies whether the driver considers whitespace and punctuation as base characters for purposes of comparison.

Data Type: CollationAlternate
Default: CollationAlternate.NonIgnorable (spaces and punctuation are considered base characters)

Alternate

maxVariable

(Optional) Specifies which characters the driver considers ignorable when the alternate argument is CollationAlternate.Shifted.

Data Type: CollationMaxVariable
Default: CollationMaxVariable.Punctuation (the driver ignores punctuation and spaces)

MaxVariable

normalization

(Optional) Specifies whether the driver normalizes text as needed.

Most text doesn't require normalization. For more information about normalization, see the ICU documentation.

Data Type: boolean
Default: false

Normalization

backwards

(Opcional) Especifica se as strings que contêm diacríticos são ordenadas da parte de trás da string para a frente.

Tipo de dados: boolean
Padrão: false

Backwards

Para obter mais informações sobre agrupamento, consulte a página Agrupamento no manual do MongoDB Server.

Importante

Você pode habilitar pré-imagens e pós-imagens em collections somente se seu sistema usar MongoDB v6.0 ou posterior.

Por padrão, quando você executa uma operação em uma collection, o evento de alteração correspondente inclui somente o delta dos campos modificados por essa operação. Para ver o documento completo antes ou depois de uma alteração, crie um objeto ChangeStreamOptions e especifique as opções FullDocumentBeforeChange ou FullDocument . Em seguida, passe o objeto ChangeStreamOptions para o método Watch() ou WatchAsync() .

A pré-imagem é a versão completa de um documento antes de uma alteração. Para incluir a pré-imagem no evento de fluxo de alteração, defina a opção FullDocumentBeforeChange para um dos seguintes valores:

  • ChangeStreamFullDocumentBeforeChangeOption.WhenAvailable: o evento de alteração inclui uma pré-imagem do documento modificado para eventos de alteração somente se a pré-imagem estiver disponível.

  • ChangeStreamFullDocumentBeforeChangeOption.Required: o evento de alteração inclui uma pré-imagem do documento modificado para eventos de alteração. Se a pré-imagem não estiver disponível, o driver gerará um erro.

A pós-imagem é a versão completa de um documento após uma alteração. Para incluir a pós-imagem na alteração de evento de fluxo, defina a opção FullDocument para um dos seguintes valores:

  • ChangeStreamFullDocumentOption.UpdateLookup: o evento de alteração inclui uma cópia de todo o documento alterado de algum tempo após a alteração.

  • ChangeStreamFullDocumentOption.WhenAvailable: O evento de alteração inclui uma pós-imagem do documento modificado para eventos de alteração somente se a pós-imagem estiver disponível.

  • ChangeStreamFullDocumentOption.Required: o evento de alteração inclui uma pós-imagem do documento modificado para eventos de alteração. Se a pós-imagem não estiver disponível, o driver gerará um erro.

O exemplo a seguir abre um fluxo de alteração em uma collection e inclui a pós-imagem de documentos atualizados especificando a opção FullDocument . Selecione a aba Synchronous ou Asynchronous para ver o código correspondente.

var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Restaurant>>()
.Match(change => change.OperationType == ChangeStreamOperationType.Update);
var options = new ChangeStreamOptions
{
FullDocument = ChangeStreamFullDocumentOption.UpdateLookup,
};
using (var cursor = collection.Watch(pipeline, options))
{
foreach (var change in cursor.ToEnumerable())
{
Console.WriteLine(change.FullDocument.ToBsonDocument());
}
}
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Restaurant>>()
.Match(change => change.OperationType == ChangeStreamOperationType.Update);
var options = new ChangeStreamOptions
{
FullDocument = ChangeStreamFullDocumentOption.UpdateLookup,
};
using var cursor = await collection.WatchAsync(pipeline, options);
await cursor.ForEachAsync(change =>
{
Console.WriteLine(change.FullDocument.ToBsonDocument());
});

Executar o exemplo de código anterior e atualizar um documento que tenha um valor de resulta na seguinte saída do "name" "Blarney Castle" :

{ "_id" : ObjectId("..."), "name" : "Blarney Castle", "restaurant_id" : "40366356",
"cuisine" : "Traditional Irish", "address" : { "building" : "202-24", "coord" : [-73.925044200000002, 40.5595462],
"street" : "Rockaway Point Boulevard", "zipcode" : "11697" }, "borough" : "Queens", "grades" : [...] }

Para saber mais sobre pré e pós-imagens, consulte Change Streams com pré e pós-imagens de documentos no manual do MongoDB Server .

Para saber mais sobre fluxos de alterações, consulte Change Streams de alterações no manual do MongoDB Server .

Para saber mais sobre qualquer um dos métodos ou tipos discutidos neste guia, consulte a seguinte documentação da API: