Definição
Sintaxe
O estágio $unionWith tem a seguinte sintaxe:
{ $unionWith: { coll: "<collection>", pipeline: [ <stage1>, ... ] } } 
Para incluir todos os documentos da collection especificada sem processamento, você pode usar o formato simplificado:
{ $unionWith: "<collection>" }  // Include all documents from the specified collection 
O estágio $unionWith recebe um documento com os seguintes campos:
| Campo | necessidade | Descrição | 
|---|---|---|
| Obrigatório se  | A collection or visualização cujos resultados de pipeline que você deseja incluir no conjunto de resultados. Se você omitir o campo  | |
| Obrigatório se  | Um pipeline de agregação para aplicar aos documentos de entrada. 
 O pipeline não pode incluir os estágios  | 
A operação $unionWith corresponderia à seguinte declaração SQL:
SELECT * FROM Collection1 WHERE ... UNION ALL SELECT * FROM Collection2 WHERE ... 
Considerações
Resultados duplicados
Os resultados combinados do estágio anterior e do estágio $unionWith podem incluir duplicatas.
Por exemplo, crie uma collection suppliers e uma collection warehouses:
db.suppliers.insertMany([   { _id: 1, supplier: "Aardvark and Sons", state: "Texas" },   { _id: 2, supplier: "Bears Run Amok.", state: "Colorado"},   { _id: 3, supplier: "Squid Mark Inc. ", state: "Rhode Island" }, ]) 
db.warehouses.insertMany([   { _id: 1, warehouse: "A", region: "West", state: "California" },   { _id: 2, warehouse: "B", region: "Central", state: "Colorado"},   { _id: 3, warehouse: "C", region: "East", state: "Florida" }, ]) 
A seguinte aggregation combina os resultados da projeção de campo state das collections suppliers e warehouse.
db.suppliers.aggregate([    { $project: { state: 1, _id: 0 } },    { $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} } ]) 
O conjunto de resultados contém duplicatas:
{ "state" : "Texas" } { "state" : "Colorado" } { "state" : "Rhode Island" } { "state" : "California" } { "state" : "Colorado" } { "state" : "Florida" } 
Para remover as duplicatas, você pode incluir um estágio $group para agrupar pelo campo state:
db.suppliers.aggregate([    { $project: { state: 1, _id: 0 } },    { $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} },    { $group: { _id: "$state" } } ]) 
O conjunto de resultados não contém mais duplicatas:
 { "_id" : "California" }  { "_id" : "Texas" }  { "_id" : "Florida" }  { "_id" : "Colorado" }  { "_id" : "Rhode Island" } 
$unionWith uma collection fragmentada
Se o estágio $unionWithfizer parte do pipeline, a collection $unionWith não poderá ser fragmentada. Por exemplo, na seguinte operação de agregação , a coleção inventory_q1 não pode ser fragmentada:
db.suppliers.aggregate([    {       $lookup: {          from: "warehouses",          let: { order_item: "$item", order_qty: "$ordered" },          pipeline: [             ...             { $unionWith: { coll: "inventory_q1", pipeline: [ ... ] } },             ...          ],          as: "stockdata"       }    } ]) 
Agrupamentos
Se db.collection.aggregate() incluir um agrupamento, esse agrupamento será utilizado para a operação, ignorando quaisquer outros agrupamentos.
Se db.collection.aggregate() não incluir um agrupamento, o método db.collection.aggregate() utilizará o agrupamento para o agrupamento/visualização de nível superior no qual db.collection.aggregate() é executado:
- Se $unionWith coll for uma coleção, seu agrupamento será ignorado. 
- Se $unionWith coll for uma visualização, seu agrupamento deverá corresponder ao da coleção/visualização de nível superior. Caso contrário, a operação apresentará erro. 
Suporte do Atlas Search
A partir do MongoDB 6.0, você pode especificar o $search do Atlas Search  ou o estágio do $searchMeta no pipeline de $unionWith para pesquisar coleções no cluster do Atlas. O estágio $search ou $searchMeta deve ser o primeiro dentro do pipeline $unionWith.
Para ver um exemplo de $unionWith com $search, consulte o tutorial Como executar uma query $search do Atlas Search usando $unionWith.
Aviso
As queries que usam $unionWith com $search no subpipeline podem falhar durante uma atualização de um conjunto de réplicas para um cluster fragmentado que esteja executando o MongoDB v7.0 se a collection não estiver distribuída em vários shards. Para mitigar isso, implemente mais de um shard em seu cluster e fragmente a coleção de forma que vários blocos estejam espalhados por vários fragmentos.
Restrições
| Restrições | Descrição | 
|---|---|
| Um pipeline de agregação não pode usar  | |
| Collection fragmentada | Se o estágio  | 
| O  pipeline $unionWith não pode incluir o  | |
| O  pipeline $unionWith não pode incluir o  | 
Exemplos
Criar relatórios de vendas a partir da união de collections de dados anuais
Os exemplos a seguir usam o estágio $unionWith para combinar dados e retornar resultados de várias coleções. Nesses exemplos, cada coleção contém um ano de dados de vendas.
Preencher dados de amostra
- Criar uma coleção - sales_2017com os seguintes documentos:- db.sales_2017.insertMany( [ - { store: "General Store", item: "Chocolates", quantity: 150 }, - { store: "ShopMart", item: "Chocolates", quantity: 50 }, - { store: "General Store", item: "Cookies", quantity: 100 }, - { store: "ShopMart", item: "Cookies", quantity: 120 }, - { store: "General Store", item: "Pie", quantity: 10 }, - { store: "ShopMart", item: "Pie", quantity: 5 } - ] ) 
- Criar uma coleção - sales_2018com os seguintes documentos:- db.sales_2018.insertMany( [ - { store: "General Store", item: "Cheese", quantity: 30 }, - { store: "ShopMart", item: "Cheese", quantity: 50 }, - { store: "General Store", item: "Chocolates", quantity: 125 }, - { store: "ShopMart", item: "Chocolates", quantity: 150 }, - { store: "General Store", item: "Cookies", quantity: 200 }, - { store: "ShopMart", item: "Cookies", quantity: 100 }, - { store: "ShopMart", item: "Nuts", quantity: 100 }, - { store: "General Store", item: "Pie", quantity: 30 }, - { store: "ShopMart", item: "Pie", quantity: 25 } - ] ) 
- Criar uma coleção - sales_2019com os seguintes documentos:- db.sales_2019.insertMany( [ - { store: "General Store", item: "Cheese", quantity: 50 }, - { store: "ShopMart", item: "Cheese", quantity: 20 }, - { store: "General Store", item: "Chocolates", quantity: 125 }, - { store: "ShopMart", item: "Chocolates", quantity: 150 }, - { store: "General Store", item: "Cookies", quantity: 200 }, - { store: "ShopMart", item: "Cookies", quantity: 100 }, - { store: "General Store", item: "Nuts", quantity: 80 }, - { store: "ShopMart", item: "Nuts", quantity: 30 }, - { store: "General Store", item: "Pie", quantity: 50 }, - { store: "ShopMart", item: "Pie", quantity: 75 } - ] ) 
- Criar uma coleção - sales_2020com os seguintes documentos:- db.sales_2020.insertMany( [ - { store: "General Store", item: "Cheese", quantity: 100, }, - { store: "ShopMart", item: "Cheese", quantity: 100}, - { store: "General Store", item: "Chocolates", quantity: 200 }, - { store: "ShopMart", item: "Chocolates", quantity: 300 }, - { store: "General Store", item: "Cookies", quantity: 500 }, - { store: "ShopMart", item: "Cookies", quantity: 400 }, - { store: "General Store", item: "Nuts", quantity: 100 }, - { store: "ShopMart", item: "Nuts", quantity: 200 }, - { store: "General Store", item: "Pie", quantity: 100 }, - { store: "ShopMart", item: "Pie", quantity: 100 } - ] ) 
Relatório 1: todas as vendas por ano e lojas e itens
A seguinte agregação cria um relatório de vendas anual que lista todas as vendas por trimestre e lojas. O pipeline usa $unionWith para combinar documentos de todas as quatro coleções:
db.sales_2017.aggregate( [    { $set: { _id: "2017" } },    { $unionWith: { coll: "sales_2018", pipeline: [ { $set: { _id: "2018" } } ] } },    { $unionWith: { coll: "sales_2019", pipeline: [ { $set: { _id: "2019" } } ] } },    { $unionWith: { coll: "sales_2020", pipeline: [ { $set: { _id: "2020" } } ] } },    { $sort: { _id: 1, store: 1, item: 1 } } ] ) 
Especificamente, o aggregation pipeline usa:
- Um estágio - $setpara atualizar o campo- _idpara conter o ano.
- Uma sequência de estágios - $unionWithpara combinar todos os documentos das quatro coleções, cada qual também usando o estágio- $setem seus documentos.
- Um estágio - $sortpara classificar pelo- _id(o ano),- storee- item.
Resultado do pipeline:
{ "_id" : "2017", "store" : "General Store", "item" : "Chocolates", "quantity" : 150 } { "_id" : "2017", "store" : "General Store", "item" : "Cookies", "quantity" : 100 } { "_id" : "2017", "store" : "General Store", "item" : "Pie", "quantity" : 10 } { "_id" : "2017", "store" : "ShopMart", "item" : "Chocolates", "quantity" : 50 } { "_id" : "2017", "store" : "ShopMart", "item" : "Cookies", "quantity" : 120 } { "_id" : "2017", "store" : "ShopMart", "item" : "Pie", "quantity" : 5 } { "_id" : "2018", "store" : "General Store", "item" : "Cheese", "quantity" : 30 } { "_id" : "2018", "store" : "General Store", "item" : "Chocolates", "quantity" : 125 } { "_id" : "2018", "store" : "General Store", "item" : "Cookies", "quantity" : 200 } { "_id" : "2018", "store" : "General Store", "item" : "Pie", "quantity" : 30 } { "_id" : "2018", "store" : "ShopMart", "item" : "Cheese", "quantity" : 50 } { "_id" : "2018", "store" : "ShopMart", "item" : "Chocolates", "quantity" : 150 } { "_id" : "2018", "store" : "ShopMart", "item" : "Cookies", "quantity" : 100 } { "_id" : "2018", "store" : "ShopMart", "item" : "Nuts", "quantity" : 100 } { "_id" : "2018", "store" : "ShopMart", "item" : "Pie", "quantity" : 25 } { "_id" : "2019", "store" : "General Store", "item" : "Cheese", "quantity" : 50 } { "_id" : "2019", "store" : "General Store", "item" : "Chocolates", "quantity" : 125 } { "_id" : "2019", "store" : "General Store", "item" : "Cookies", "quantity" : 200 } { "_id" : "2019", "store" : "General Store", "item" : "Nuts", "quantity" : 80 } { "_id" : "2019", "store" : "General Store", "item" : "Pie", "quantity" : 50 } { "_id" : "2019", "store" : "ShopMart", "item" : "Cheese", "quantity" : 20 } { "_id" : "2019", "store" : "ShopMart", "item" : "Chocolates", "quantity" : 150 } { "_id" : "2019", "store" : "ShopMart", "item" : "Cookies", "quantity" : 100 } { "_id" : "2019", "store" : "ShopMart", "item" : "Nuts", "quantity" : 30 } { "_id" : "2019", "store" : "ShopMart", "item" : "Pie", "quantity" : 75 } { "_id" : "2020", "store" : "General Store", "item" : "Cheese", "quantity" : 100 } { "_id" : "2020", "store" : "General Store", "item" : "Chocolates", "quantity" : 200 } { "_id" : "2020", "store" : "General Store", "item" : "Cookies", "quantity" : 500 } { "_id" : "2020", "store" : "General Store", "item" : "Nuts", "quantity" : 100 } { "_id" : "2020", "store" : "General Store", "item" : "Pie", "quantity" : 100 } { "_id" : "2020", "store" : "ShopMart", "item" : "Cheese", "quantity" : 100 } { "_id" : "2020", "store" : "ShopMart", "item" : "Chocolates", "quantity" : 300 } { "_id" : "2020", "store" : "ShopMart", "item" : "Cookies", "quantity" : 400 } { "_id" : "2020", "store" : "ShopMart", "item" : "Nuts", "quantity" : 200 } { "_id" : "2020", "store" : "ShopMart", "item" : "Pie", "quantity" : 100 } 
Relatório 2: vendas agregadas por itens
A seguinte agregação cria um relatório de vendas que lista a quantidade de vendas por item. O pipeline usa $unionWith para combinar documentos de todos os quatro anos:
db.sales_2017.aggregate( [    { $unionWith: "sales_2018" },    { $unionWith: "sales_2019" },    { $unionWith: "sales_2020" },    { $group: { _id: "$item", total: { $sum: "$quantity" } } },    { $sort: { total: -1 } } ] ) 
- A sequência de estágios - $unionWithrecupera documentos das coleções especificadas para o pipeline:
- O estágio - $groupagrupa pelo- itemcampo e usa- $sumpara calcular a quantidade total de vendas por- item.
- O estágio - $sortordena os documentos- totalem ordem decrescente.
Resultado do pipeline:
{ "_id" : "Cookies", "total" : 1720 } { "_id" : "Chocolates", "total" : 1250 } { "_id" : "Nuts", "total" : 510 } { "_id" : "Pie", "total" : 395 } { "_id" : "Cheese", "total" : 350 } 
Crie uma união com documentos especificados
Você pode usar $unionWith para realizar uma união com documentos especificados no campo pipeline. Ao especificar um estágio $documents no campo pipeline, você realiza uma união com documentos que não estão armazenados em uma coleção separada.
Criar uma coleção cakeFlavors:
db.cakeFlavors.insertMany( [    { _id: 1, flavor: "chocolate" },    { _id: 2, flavor: "strawberry" },    { _id: 3, flavor: "cherry" } ] ) 
A seguinte operação $unionWith executa uma união com documentos especificados no campo pipeline $documents :
db.cakeFlavors.aggregate( [    {       $unionWith: {          pipeline: [             {                $documents: [                   { _id: 4, flavor: "orange" },                   { _id: 5, flavor: "vanilla", price: 20 }                ]             }          ]       }    } ] ) 
Saída:
[    { _id: 1, flavor: 'chocolate' },    { _id: 2, flavor: 'strawberry' },    { _id: 3, flavor: 'cherry' },    { _id: 4, flavor: 'orange' },    { _id: 5, flavor: 'vanilla', price: 20 } ] 
Os exemplos de C# nesta página utilizam o banco de dados sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver MongoDB .NET/C#.
A seguinte classe Movie modela os documentos na collection sample_mflix.movies:
public class Movie {     public ObjectId Id { get; set; }     public int Runtime { get; set; }          public string Title { get; set; }     public string Rated { get; set; }     public List<string> Genres { get; set; }     public string Plot { get; set; }          public ImdbData Imdb { get; set; }     public int Year { get; set; }     public int Index { get; set; }          public string[] Comments { get; set; }         []     public DateTime LastUpdated { get; set; } } 
Observação
ConventionPack para Pascal Case
As classes C# nesta página usam Pascal case para seus nomes de propriedade, mas os nomes de campo na coleção MongoDB usam Camel case. Para considerar essa diferença, você pode usar o seguinte código para registrar um ConventionPack quando o aplicativo iniciar:
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true); 
Para usar o driver MongoDB .NET/C# para adicionar um $unionWith estágio a um pipeline de agregação , chame o método unionWith() em um PipelineDefinition objeto.
O exemplo a seguir cria um estágio de pipeline que combina os documentos recebidos da coleção sample_mflix.movies com os documentos Movie na coleção sample_mflix.Movies:
var firstMovieCollection = client.GetDatabase("sample_mflix").GetCollection<Movie>("movies"); var secondMovieCollection = client.GetDatabase("sample_mflix").GetCollection<Movie>("Movies"); var pipeline = new EmptyPipelineDefinition<Movie>()     .UnionWith(         withCollection: secondMovieCollection,         withPipeline: new EmptyPipelineDefinition<Movie>()); var allMovieDocuments = firstMovieCollection.Aggregate(pipeline);  
Os exemplos do Node.js nesta página utilizam o banco de dados do sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js
Para usar o driver Node.js do MongoDB para adicionar um estágio $unionWith a um pipeline de agregação , use o operador $unionWith em um objeto de pipeline.
O exemplo a seguir cria um estágio de pipeline que combina os documentos recebidos da collection sample_mflix.movies com os documentos movie na collection sample_mflix.Movies. Em seguida, o exemplo executa o agregação pipeline:
const db = client.db("sample_mflix"); const collection = db.collection("movies"); const pipeline = [{ $unionWith: { coll: "Movies" } }]; const cursor = collection.aggregate(pipeline); return cursor;