Página inicial do Docs → Desenvolver aplicações → Manual do MongoDB
$changeStreamSplitLargeEvent (agregação)
Nesta página
Definição
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
efullDocumentBeforeChange
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: {} }
Comportamento
$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. |
Exemplo
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.