Definição
Observação
Esta página descreve o estágio $merge, que gera resultados do pipeline de agregação para uma coleção. Para o operador $mergeObjects, que mescla documentos em um único documento, consulte $mergeObjects.
$mergeGrava os resultados do pipeline de agregação para uma coleção especificada. O operador
$mergedeve ser o último estágio do pipeline.O estágio
$merge:Pode enviar para uma coleção no mesmo banco de dados ou em um banco de dados diferente.
Pode gerar saída para a mesma coleção que está sendo agregada. Para obter mais informações, consulte Saída para a mesma coleção que está sendo agregada.
Considere os seguintes pontos ao usar os
$mergeestágios ou em$outum agregação pipeline:A partir do MongoDB 5.0, os pipelines com um estágio
$mergepoderão ser executados em nós secundários do conjunto de réplicas se todos os nós do cluster tiverem o featureCompatibilityVersion definido como5.0ou superior e a preferência de leitura permitir leituras secundárias.nas versões anteriores do MongoDB , os pipelines com estágios
$outou$mergesempre são executados no nó principal, e a preferência de leitura não é considerada.
Cria uma nova coleta se a coleta de saída ainda não existir.
Pode incorporar resultados (inserir novos documentos, mesclar documentos, substituir documentos, manter documentos existentes, falhar a operação, processar documentos com um pipeline de atualização personalizado) a uma coleção existente.
Pode gerar saída para uma coleção fragmentada. A coleta de entrada também pode ser fragmentada.
Para uma comparação com o estágio, que também gera os resultados da agregação em uma
$outcoleção,$merge$outconsulte Comparação e .
Observação
Visualizações materializadas sob demanda
$merge pode incorporar os resultados do pipeline em uma coleção de saída existente em vez de executar uma substituição completa da coleção. Essa funcionalidade permite que os usuários criem exibições materializadas sob demanda, em que o conteúdo da coleção de saída é atualizado de forma incremental quando o pipeline é executado.
Para obter mais informações sobre esse caso de uso, consulte Exibições materializadas sob demanda , bem como os exemplos nesta página.
As visualizações materializadas são separadas das exibições somente para leitura. Para obter informações sobre como criar visualizações somente para leitura, consulte exibições somente para leitura.
Compatibilidade
Você pode utilizar o $merge para implantações hospedadas nos seguintes ambientes:
- MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
$merge tem a seguinte sintaxe:
{ $merge: { into: <collection> -or- { db: <db>, coll: <collection> }, on: <identifier field> -or- [ <identifier field1>, ...], // Optional let: <variables>, // Optional whenMatched: <replace|keepExisting|merge|fail|pipeline>, // Optional whenNotMatched: <insert|discard|fail> // Optional } }
Por exemplo:
{ $merge: { into: "myOutput", on: "_id", whenMatched: "replace", whenNotMatched: "insert" } }
Se utilizar todas as opções padrão para $merge, inclusive gravar em uma coleção no mesmo banco de dados, você poderá utilizar o formulário simplificado:
{ $merge: <collection> } // Output collection is in the same database
O estágio $merge recebe um documento com os seguintes campos:
Campo | Descrição | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
A coleção de saída. Especifique uma das seguintes opções:
Se a coleção de saída não existir, o
A coleção de saída pode ser uma coleção fragmentada. | |||||||||||
Opcional. Campo ou campos que atuam como um identificador exclusivo para um documento. O identificador determina se um documento de resultados corresponde a um documento existente na coleção de resultados. Especifique uma das seguintes opções:
Para o campo ou campos especificados:
O valor padrão para ativado depende da coleção de saída:
| |||||||||||
Opcional. O comportamento de Você pode especificar:
| |||||||||||
Opcional. Especifica variáveis para uso no pipeline whenMatched. Especifique um documento com os nomes de variáveis e expressões de valor: Se não for especificado, Para acessar as variáveis no pipeline whenMatched: Especifique o prefixo do sinal de dólar duplo ($$) juntamente com o nome da variável no formulário Para obter exemplos, consulte Use Variables to Customize the Merge (Usar variáveis para personalizar a mesclagem). | |||||||||||
Opcional. O comportamento de Você pode especificar uma das strings de ação predefinidas:
|
Considerações
_id Geração de campo
Se o campo _id não estiver presente em um documento dos resultados do pipeline de agregação, o estágio $merge o gerará automaticamente.
Por exemplo, no seguinte pipeline de agregação, $project exclui o campo _id dos documentos passados para $merge. Quando $merge grava esses documentos para o "newCollection", $merge gera um novo campo _id e um novo valor.
db.movies.aggregate( [ { $project: { _id: 0 } }, { $merge : { into : "newCollection" } } ] )
Criar uma nova coleção se a coleta de saída não for existente
A operação $merge cria uma nova coleção se a coleção de saída especificada não existir.
A coleção de saída é criada quando
$mergegrava o primeiro documento na coleção e fica imediatamente visível.Se a agregação falhar, quaisquer gravações concluídas pelo
$mergeantes do erro não serão revertidas.
Observação
Para um conjunto de réplicas ou um standalone, se o banco de dados de saída não existir, $merge também criará o banco de dados.
Para um cluster fragmentado, o banco de dados de saída especificado já deve existir.
Se a coleção de saída não existir, $merge exigirá que o identificador on seja o _id campo. Para usar um on valor de campo diferente para uma coleção que não existe, você pode criar a coleção primeiro criando um índice único no(s) campo(s) desejado(s) primeiro. Por exemplo, se a coleção de saída newDailyCommentCount não existir e você quiser especificar o commentDate campo como o identificador ligado:
db.newDailyCommentCount.createIndex( { commentDate: 1 }, { unique: true } ) db.comments.aggregate( [ { $match: { date: { $gte: new Date("2002-01-01"), $lt: new Date("2002-02-01") } } }, { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, count: { $sum: 1 } } }, { $project: { _id: 0, commentDate: { $toDate: "$_id" }, count: 1 } }, { $merge : { into : "newDailyCommentCount", on: "commentDate" } } ] )
Saída para uma coleção compartilhada
O estágio $merge pode gerar saída para uma coleção fragmentada. Quando a coleção de saída é fragmentada, $merge usa o campo _id e todos os campos da chave de shard com hash como identificador padrão. Se você substituir o padrão, o identificador ativado deverá incluir todos os campos de chave de fragmento :
{ $merge: { into: "<shardedColl>" or { db:"<sharding enabled db>", coll: "<shardedColl>" }, on: [ "<shardkeyfield1>", "<shardkeyfield2>",... ], // Shard key fields and any additional fields let: <variables>, // Optional whenMatched: <replace|keepExisting|merge|fail|pipeline>, // Optional whenNotMatched: <insert|discard|fail> // Optional } }
Por exemplo, utilize o método sh.shardCollection() para criar uma nova coleção fragmentada moviesByYearAndRating com o campo rated como a chave fragmentada.
sh.shardCollection( "sample_mflix.moviesByYearAndRating", // Namespace of the collection to shard { rated: 1 }, // Shard key );
A moviesByYearAndRating coleção conterá documentos com estatísticas de filmes por ano (year campo) e classificação de conteúdo (chave de shard); especificamente, o identificador ligado é ["year", "rated"] (a ordem dos campos não importa). Como $merge requer um índice único com chaves que correspondam aos campos do identificador ligado, crie o índice único (a ordem dos campos não importa): []1
db.moviesByYearAndRating.createIndex( { rated: 1, year: 1 }, { unique: true } )
Com a coleção fragmentada moviesByYearAndRating e o índice único criado, você pode usar $merge para gerar os resultados da agregação para essa coleção, correspondendo a [ "year", "rated" ], como neste exemplo:
db.movies.aggregate( [ { $match: { rated: { $ne: null }, year: { $ne: null } } }, { $group: { _id: { year: "$year", rated: "$rated" }, movieCount: { $sum: 1 } } }, { $project: { _id: 0, year: "$_id.year", rated: "$_id.rated", movieCount: 1 } }, { $merge: { into: "moviesByYearAndRating", "on": [ "year", "rated" ], whenMatched: "replace", whenNotMatched: "insert" } } ] )
| [1] | O método No exemplo anterior, como o identificador |
Substituir documentos ($merge) versus Substituir coleção ($out)
$merge pode substituir um documento existente na coleção de saída se os resultados da agregação contiverem um documento ou documentos que correspondam com base na especificação. Como tal, $merge pode substituir todos os documentos na coleção existente se os resultados da agregação incluírem documentos correspondentes para todos os documentos existentes na coleção e você especificar "substituir" para whenMatched.
No entanto, para substituir uma coleção existente, independentemente dos resultados da agregação, use $out em vez disso.
Documentos existentes, _id e valores da chave de fragmento
Os erros do $merge se o $merge resultar em uma alteração no valor de _id de um documento existente.
Dica
Para evitar esse erro, se o campo on não incluir o _id campo, remova o _id campo nos resultados da agregação para evitar o erro, como em um $unset estágio de anterior e assim por diante.
Além disso, para uma coleção fragmentada, $merge também gera um erro se resultar em uma alteração no valor da chave fragmentada de um documento existente.
As gravações concluídas pelo $merge antes do erro não serão revertidas.
Restrições de índice único
Se o índice único usado por $merge para o(s) campo(s) for descartado no meio da agregação, não haverá garantias de que a agregação será eliminada. Se a agregação continuar, não haverá garantias de que os documentos não tenham on valores de campo duplicados.
Se o $merge tentar gravar um documento que viole qualquer índice exclusivo na coleção de saída, a operação gerará um erro. Por exemplo:
Insira um documento não correspondente que viole um índice exclusivo diferente do índice no(s) campo(s) em.
Substituir um documento existente por um novo documento que viole um índice exclusivo que não seja o índice do(s) campo(s) ligado(s).
Mescle os documentos correspondentes que resultam em um documento que viola um índice exclusivo diferente do índice no(s) campo(s) ligado(s).
Validação de esquema
Se sua coleção usar validação de esquema e tiver validationAction definido como error, inserir um documento inválido ou atualizar um documento com valores inválidos com $merge gerará um MongoServerError e o documento não será gravado na coleção de destino. Se houver vários documentos inválidos, apenas o primeiro documento inválido encontrado gerará um erro. Todos os documentos válidos são gravados na coleção de destino e todos os documentos inválidos não são gravados.
whenMatched Comportamento de pipeline
$merge insere o documento diretamente na coleção de saída quando todas as seguintes condições forem verdadeiras:
O valor de whenMatched é um pipeline de agregação .
O valor de whenNotMatched
inserté.Não há correspondência para um documento na coleção de saída.
$merge e comparação $out
Com a introdução de $merge, o MongoDB fornece dois estágios, $merge e $out, para gravar os resultados do pipeline de agregação em uma coleção:
$merge | |
|---|---|
|
|
|
|
|
|
|
|
|
|
Saída para a mesma coleção que está sendo agregada
Aviso
Quando$mergegera saídas para a mesma coleção que está sendo agregada, os documentos podem ser atualizados várias vezes ou a operação pode resultar em um loop infinito. Esse comportamento ocorre quando a atualização realizada pelo$mergealtera a localização física dos documentos armazenados no disco. Quando a localização física de um documento muda, $mergepode considerá-lo um documento totalmente novo , resultando em atualizações adicionais. Para obter mais informações sobre esse comportamento, consulte Problema de Halloween.
$merge pode gerar saída para a mesma coleção que está sendo agregada. Você também pode gerar saída para uma coleção que aparece em outros estágios do pipeline,$lookup como.
Restrições
Restrições | Descrição |
|---|---|
Um pipeline de agregação não pode usar | |
Um pipeline de agregação não pode usar | |
ver definição | Uma definição de visualização não pode incluir o estágio |
| O |
| O |
| O |
|