Definição
O estágio $merge especifica uma conexão no Connection Registry para gravar mensagens. A conexão deve ser uma conexão do Atlas.
Colocação
$merge deve ser o último estágio de qualquer pipeline em que apareça. Você pode usar apenas um estágio $merge por pipeline.
Sintaxe
The Atlas Stream Processing version of $merge uses most of the same fields as the Atlas Data Federation version. Atlas Stream Processing also uses the following fields that are either unique to its implementation of $merge, or modified to suit it. To learn more about the fields shared with Atlas Data Federation $merge, see $merge syntax.
Um estágio de pipeline do $merge tem a seguinte forma de protótipo:
{ "$merge": { "into": { "connectionName": "<registered-atlas-connection>", "db": "<registered-database-name>" | <expression>, "coll": "<atlas-collection-name>" | <expression> }, "on": "<identifier field>" | [ "<identifier field1>", ...], "let": { <var_1>: <expression>, <var_2>: <expression>, …, <var_n>: <expression> }, "whenMatched": "replace | keepExisting | merge | delete | <pipeline> | <expression>", "whenNotMatched": "insert | discard | expression", "parallelism": <integer> } }
Campo | necessidade | Descrição |
|---|---|---|
| Obrigatório | Simplificado para reproduzir o suporte do Atlas Stream Processing para Para aprender mais, consulte esta descrição dos campos do Atlas Data Federation |
| Opcional | Amplia a funcionalidade em comparação com o estágio Quando configurado para Ao usar um valor de expressão dinâmica, ele deverá ser resolvido para uma das seguintes strings:
|
| Opcional | Amplia a funcionalidade em comparação com o estágio Ao usar um valor de expressão dinâmica, ele deverá ser resolvido para uma das seguintes strings:
|
| Condicional | Número de threads para distribuir operações de gravação. O padrão é O valor máximo que você pode definir depende do tier do seu processador de stream. Para saber mais, consulte o Guia de seleção do tier do Atlas Stream Processing. Cada processador de fluxo tem um valor máximo de paralelismo cumulativo determinado por seu nível. O paralelismo cumulativo de um processador de fluxo é calculado da seguinte forma:
Where Por exemplo, se o seu estágio Se um processador de fluxo exceder o paralelismo cumulativo máximo para seu nível, o Atlas Stream Processing lançará um erro e o avisará sobre o nível mínimo de processador necessário para o nível pretendido de paralelismo. Você deve dimensionar o processador para um nível superior ou reduzir os valores de paralelismo de seus estágios para resolver o erro. Para saber mais, consulte Stream Processing. |
Comportamento
Limitações
The on field has special requirements for $merge against sharded collections. To learn more, see $merge syntax.
$merge can't write to time series collections. To write documents to time series collections, use the $emit stage.
Você precisa ter a função de administrador do Atlas para usar $merge em coleções fragmentadas.
Expressões Dinâmicas
You can use a field or dynamic expression as the value of the following fields:
into.dbinto.coll
Isso permite que seu processador de fluxo grave mensagens em diferentes collection de destino do Atlas, mensagem por mensagem.
Exemplo
Você tem um fluxo de eventos de transação que gera mensagens da seguinte forma:
{ "customer": "Very Important Industries", "customerStatus": "VIP", "tenantId": 1, "transactionType": "subscription" } { "customer": "N. E. Buddy", "customerStatus": "employee", "tenantId": 5, "transactionType": "requisition" } { "customer": "Khan Traktor", "customerStatus": "contractor", "tenantId": 11, "transactionType": "billableHours" }
Para classificar cada um deles em um reconhecimento de data center e collection Atlas distintos, você pode escrever o seguinte estágio $merge :
$merge: { into: { connectionName: "db1", db: "$customerStatus", coll: "$transactionType" } }
Este estágio $merge :
Escreve a mensagem
Very Important Industriespara uma collection Atlas denominadaVIP.subscription.Escreve a mensagem
N. E. Buddypara uma collection Atlas denominadaemployee.requisition.Escreve a mensagem
Khan Traktorpara uma collection Atlas denominadacontractor.billableHours.
You can only use dynamic expressions that evaluate to strings. For more information on dynamic expressions, see expression operators.
If you specify a database or collection with a dynamic expression, but Atlas Stream Processing cannot evaluate the expression for a given message, Atlas Stream Processing sends that message to the dead letter queue if configured and processes subsequent messages. If there is no dead letter queue configured, then Atlas Stream Processing skips the message completely and processes subsequent messages.
Salvando dados de tópicos do Kafka
Para salvar dados de streaming de múltiplos tópicos do Apache Kafka em coleções no seu cluster Atlas, utilize o estágio $merge com o estágio $source. A etapa $source especifica os tópicos dos quais ler dados. O estágio $merge grava os dados na coleção de destino.
Use a seguinte sintaxe:
{ "$source": { "connectionName": "<registered-kafka-connection>", "topic": [ "<topic-name-1>", "<topic-name-2>", ... ] } }, { "$merge": { "into": { "connectionName": "<registered-atlas-connection>", "db": "<registered-database-name>" | <expression>, "coll": "<atlas-collection-name>" | <expression> } }, ... }
Exemplos
Exemplo básico
A streaming data source generates detailed weather reports from various locations, conformant to the schema of the Sample Weather Dataset. The following aggregation has three stages:
O estágio
$sourceestabelece uma conexão com o broker do Apache Kafka coletando esses relatórios em um tópico chamadomy_weatherdata, expondo cada registro à medida que ele é assimilado nos estágios de agregação subsequentes. Esse estágio também substitui o nome do campo de carimbo de data/hora que ele projeta, definindo-o comoingestionTime.The
$matchstage excludes documents that have adewPoint.valueof less than or equal to5.0and passes along the documents withdewPoint.valuegreater than5.0to the next stage.The
$mergestage writes the output to an Atlas collection namedstreamin thesample_weatherstreamdatabase. If no such database or collection exist, Atlas creates them.
{ '$source': { connectionName: 'sample_weatherdata', topic: 'my_weatherdata', tsFieldName: 'ingestionTime' } }, { '$match': { 'dewPoint.value': { '$gt': 5 } } }, { '$merge': { into: { connectionName: 'weatherStreamOutput', db: 'sample_weatherstream', coll: 'stream' } } }
Para visualizar os documentos na coleção sample_weatherstream.stream resultante, conecte-se ao cluster Atlas e execute o seguinte comando:
db.getSiblingDB("sample_weatherstream").stream.find()
{ _id: ObjectId('66ad2edfd4fcac13b1a28ce3'), airTemperature: { quality: '1', value: 27.7 }, atmosphericPressureChange: { quantity24Hours: { quality: '9', value: 99.9 }, quantity3Hours: { quality: '1' }, tendency: { code: '1', quality: '1' } }, atmosphericPressureObservation: { altimeterSetting: { quality: '1', value: 1015.9 }, stationPressure: { quality: '1', value: 1021.9 } }, callLetters: 'CGDS', dataSource: '4', dewPoint: { quality: '9', value: 25.7 }, elevation: 9999, extremeAirTemperature: { code: 'N', period: 99.9, quantity: '9', value: -30.4 }, ingestionTime: ISODate('2024-08-02T19:09:18.071Z'), liquidPrecipitation: { condition: '9', depth: 160, period: 24, quality: '2' }, pastWeatherObservationManual: { atmosphericCondition: { quality: '1', value: '8' }, period: { quality: '9', value: 3 } }, position: { coordinates: [ 153.3, 50.7 ], type: 'Point' }, precipitationEstimatedObservation: { discrepancy: '4', estimatedWaterDepth: 4 }, presentWeatherObservationManual: { condition: '53', quality: '1' }, pressure: { quality: '1', value: 1016.3 }, qualityControlProcess: 'V020', seaSurfaceTemperature: { quality: '9', value: 27.6 }, sections: [ 'AA2', 'SA1', 'MW1', 'AG1', 'GF1' ], skyCondition: { cavok: 'N', ceilingHeight: { determination: 'C', quality: '1', value: 6900 } }, skyConditionObservation: { highCloudGenus: { quality: '1', value: '05' }, lowCloudGenus: { quality: '9', value: '03' }, lowestCloudBaseHeight: { quality: '9', value: 150 }, lowestCloudCoverage: { quality: '1', value: '05' }, midCloudGenus: { quality: '9', value: '08' }, totalCoverage: { opaque: '99', quality: '1', value: '06' } }, skyCoverLayer: { baseHeight: { quality: '9', value: 99999 }, cloudType: { quality: '9', value: '05' }, coverage: { quality: '1', value: '04' } }, st: 'x+35700-027900', type: 'SAO', visibility: { distance: { quality: '1', value: 4000 }, variability: { quality: '1', value: 'N' } }, waveMeasurement: { method: 'I', seaState: { code: '99', quality: '9' }, waves: { height: 99.9, period: 14, quality: '9' } }, wind: { direction: { angle: 280, quality: '9' }, speed: { quality: '1', rate: 30.3 }, type: '9' } }
Observação
O exemplo anterior é representativo. Os dados de streaming não são estáticos e cada usuário vê documentos distintos.
Replicar eventos do change stream nos Atlas clusters
You can use the $merge.whenMatched and $merge.whenNotMatched parameters to replicate the effects of Change Stream events according to their operation type.
A seguinte agregação tem quatro fases:
O estágio
$sourceestabelece uma conexão com a coleçãodb1.coll1em um cluster do Atlas por meio da conexãoatlas1.The
$addFieldsstage enriches the ingested documents with afullDocument._isDeletefield set to the value of an equality check between the"$operationTypevalue of each document and"delete". This equality evaluates to a boolean.O estágio
$replaceRootsubstitui o documento pelo valor do campo$fullDocumentenriquecido.O estágio
$mergegrava emdb1.coll1através da conexãoatlas2, realizando duas verificações em cada documento:Primeiro, o campo
whenMatchedverifica se o documento corresponde a um documento existente na coleçãodb1.coll1usando_id, que é o campo de correspondência padrão, já queonnão está explicitamente definido. Se isso acontecer efullDocument._isDeleteestiver definido comotrue, então o Atlas exclui o documento correspondente. Se corresponder efullDocument._isDeleteestiver definido comofalse, o Atlas substituirá o documento correspondente pelo novo da fonte de dados de streaming.Em segundo lugar, se o Atlas Stream Processing não encontrar tal documento correspondente e
fullDocument._isDeletefor verdadeiro, o Atlas descartará o documento em vez de gravá-lo na coleção. Se não houver um documento correspondente efullDocument._isDeletefor falso, o Atlas insere o documento da fonte de dados de streaming na coleção.
{ $source: { connectionName: “atlas1”, db: “db1”, coll: “coll1”, fullDocument: “required” } }, { $addFields: { “fullDocument._isDelete”: { $eq: [ “$operationType”, “delete” ] } } }, { $replaceRoot: { newRoot: “$fullDocument” } }, { $merge: { into: { connectionName: “atlas2”, db: “db1”, coll: “coll1” }, whenMatched: { $cond: { if: “$_isDelete”, then: “delete”, else: “replace” } }, whenNotMatched: { $cond: { if: “$_isDelete”, then: “discard”, else: “insert” } }, } }