Menu Docs

Página inicial do DocsDesenvolver aplicaçõesManual do MongoDB

$changeStreamSplitLargeEvent (agregação)

Nesta página

  • Definição
  • Comportamento
  • Exemplo
$changeStreamSplitLargeEvent

Novidade na versão 7.0: (Também disponível na 6.0.9)

Se um change stream tiver eventos grandes que excedem 16 MB, uma exceção BSONObjectTooLarge será retornada. Iniciando no MongoDB 6.0.9, você pode utilizar um estágio $changeStreamSplitLargeEvent para dividir os eventos em fragmentos menores.

Você só deve usar $changeStreamSplitLargeEvent quando estritamente necessário. Por exemplo, se o seu aplicativo exigir pré ou pós-imagens completas do documento e gerar eventos grandes que excedam 16 MB, use $changeStreamSplitLargeEvent.

Antes de decidir usar $changeStreamSplitLargeEvent, você deve primeiro tentar reduzir o tamanho do evento de alteração. Por exemplo:

  • Não solicite pré ou pós-imagens de documentos, a menos que seu aplicativo exija. Isso gera campos fullDocument e fullDocumentBeforeChange em mais casos, que normalmente são os maiores objetos em um evento de alteração.

  • Use um estágio $project para incluir somente os campos necessários para seu aplicativo. Isso reduz o tamanho do evento de alteração e evita o tempo adicional para dividir eventos grandes em fragmentos. Isso permite que mais eventos de alteração sejam retornados em cada lote.

Você só pode ter um estágio $changeStreamSplitLargeEvent em seu pipeline, e ele deve ser o último estágio. Você só pode usar $changeStreamSplitLargeEvent em um pipeline $changeStream .

$changeStreamSplitLargeEvent sintaxe:

{
$changeStreamSplitLargeEvent: {}
}

$changeStreamSplitLargeEvent divide eventos que excedem 16 MB em fragmentos e retorna os fragmentos sequencialmente usando o cursor de fluxo de alterações.

Os fragmentos são divididos para que o número máximo de campos seja retornado no primeiro fragmento. Isso garante que o contexto do evento seja retornado o mais rápido possível.

Quando o evento de alteração é dividido, somente o tamanho dos campos de nível superior é usado. $changeStreamSplitLargeEvent não processa nem divide subdocumentos recursivamente. Por exemplo, se você usar um estágio $project para criar um evento de alteração com um único campo 20 MB, o evento não será dividido e o estágio retornará um erro.

Cada fragmento tem um token de currículo. Um stream retomado usando o token de um fragmento:

  • Iniciar um novo fluxo a partir do fragmento subsequente.

  • Comece no próximo evento se retomar a partir do fragmento final na sequência.

Cada fragmento de um evento inclui um documento splitEvent :

splitEvent: {
fragment: <int>,
of: <int>
}

A tabela a seguir descreve os campos.

Campo
Descrição
fragment
Índice de fragmento, a partir de 1.
of
Número total de fragmentos para o evento.

O cenário de exemplo nesta seção mostra o uso de $changeStreamSplitLargeEvent com uma nova coleção denominada myCollection.

Crie myCollection e insira um documento com pouco menos 16 MB de dados:

db.myCollection.insertOne(
{ _id: 0, largeField: "a".repeat( 16 * 1024 * 1024 - 1024 ) }
)

largeField contém a letra repetida a.

Ative changeStreamPreAndPostImages para myCollection, o que permite que um change stream recupere um documento como ele estava antes de uma atualização (pré-imagem) e depois de uma atualização (pós-imagem):

db.runCommand( {
collMod: "myCollection",
changeStreamPreAndPostImages: { enabled: true }
} )

Crie um cursor de fluxo de alterações para monitorar as alterações em myCollection usando db.collection.watch():

myChangeStreamCursor = db.myCollection.watch(
[ { $changeStreamSplitLargeEvent: {} } ],
{ fullDocument: "required", fullDocumentBeforeChange: "required" }
)

Para o evento de fluxo de alterações:

  • fullDocument: "required" inclui o documento pós-imagem.

  • fullDocumentBeforeChange: "required" inclui a pré-imagem do documento.

Para detalhes, consulte $changeStream.

Atualize o documento em myCollection, que também produz um evento de fluxo de alteração com as imagens pré e pós do documento:

db.myCollection.updateOne(
{ _id: 0 },
{ $set: { largeField: "b".repeat( 16 * 1024 * 1024 - 1024 ) } }
)

largeField agora contém a letra repetida b.

Recupere os fragmentos de myChangeStreamCursor utilizando o método next() e armazene os fragmentos em objetos denominados firstFragment, secondFragment e thirdFragment:

const firstFragment = myChangeStreamCursor.next()
const secondFragment = myChangeStreamCursor.next()
const thirdFragment = myChangeStreamCursor.next()

Mostrar firstFragment.splitEvent:

firstFragment.splitEvent

Saída com os detalhes do fragmento:

splitEvent: { fragment: 1, of: 3 }

Da mesma forma, secondFragment.splitEvent e thirdFragment.splitEvent retornam:

splitEvent: { fragment: 2, of: 3 }
splitEvent: { fragment: 3, of: 3 }

Para examinar as chaves de objeto para firstFragment:

Object.keys( firstFragment )

Saída:

[
'_id',
'splitEvent',
'wallTime',
'clusterTime',
'operationType',
'documentKey',
'ns',
'fullDocument'
]

Para examinar o tamanho em bytes de firstFragment.fullDocument:

bsonsize( firstFragment.fullDocument )

Saída:

16776223

secondFragment contém a pré-imagem fullDocumentBeforeChange , que tem aproximadamente 16 MB de tamanho. O exemplo a seguir mostra as chaves de objeto para secondFragment:

Object.keys( secondFragment )

Saída:

[ '_id', 'splitEvent', 'fullDocumentBeforeChange' ]

thirdFragment contém o campo updateDescription , que tem aproximadamente 16 MB de tamanho. O exemplo a seguir mostra as chaves de objeto para thirdFragment:

Object.keys( thirdFragment )

Saída:

[ '_id', 'splitEvent', 'updateDescription' ]

Para mais informações sobre change streams e eventos, consulte Change Events.

← $changeStream (agregação)