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 collectionO estágio $unionWith recebe um documento com os seguintes campos:
Campo | necessidade | Descrição |
|---|---|---|
Obrigatório se | A coleção ou visualização cujos resultados de pipeline 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 Collection1WHERE ...UNION ALLSELECT *FROM Collection2WHERE ...Considerações
Resultados duplicados
Os resultados combinados do estágio anterior e do estágio $unionWith podem incluir duplicatas.
Por exemplo, a seguinte agregação combina os resultados da projeção de campo title de duas queries na coleção movies. O conjunto de resultados contém duplicatas:
db.movies.aggregate( [ { $match: { runtime: { $gt: 1000 } } }, { $project: { title: 1, _id: 0 } }, { $unionWith: { coll: "movies", pipeline: [ { $match: { runtime: { $gt: 1000 } } }, { $project: { title: 1, _id: 0 } } ] } }] )[ { title: 'Centennial' }, { title: 'Baseball' }, { title: 'Centennial' }, { title: 'Baseball' }]Para remover as duplicatas, você pode incluir um estágio $group para agrupar pelo campo title. O conjunto de resultados não contém mais duplicatas:
db.movies.aggregate( [ { $match: { runtime: { $gt: 1000 } } }, { $project: { title: 1, _id: 0 } }, { $unionWith: { coll: "movies", pipeline: [ { $match: { runtime: { $gt: 1000 } } }, { $project: { title: 1, _id: 0 } } ] } }, { $group: { _id: "$title" } }, { $sort: { _id: 1 } }] )[ { _id: 'Baseball' }, { _id: 'Centennial' }]Agrupamentos
Se o db.collection.aggregate() incluir um documento collation , a operação usará esse agrupamento e ignorará quaisquer outros agrupamentos.
Se db.collection.aggregate() não incluir um documento collation , o método db.collection.aggregate() usará 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 de pesquisa do MongoDB
A partir do MongoDB 6.0, você pode especificar o estágio MongoDB Search $search ou $searchMeta no $unionWith pipeline para pesquisar collections no Atlas cluster. O $search ou o $searchMeta deve ser o primeiro estágio dentro do pipeline $unionWith.
[{ "$unionWith": { "coll": <collection-name>, "pipeline": [{ "$search": { "<operator>": { <operator-specification> } }, ... }] }}][{ "$unionWith": { "coll": <collection-name>, "pipeline": [{ "$searchMeta": { "<collector>": { <collector-specification> } }, ... }] }}]Para ver um exemplo de $unionWith com $search, veja o tutorial do MongoDB Search Executar uma query do MongoDB Search $search usando $unionWith.
Namespaces em Subpipelines
A partir do MongoDB 8.0, os namespaces em subpipelines dentro $lookup e $unionWith são validados para garantir o uso correto dos campos from e coll:
Por
$lookup, omita o campofromse você usar um subpipeline com um estágio que não exija uma coleção especificada. Por exemplo, um estágio$documents.Da mesma forma, para
$unionWith, omita o campocoll.
Comportamento inalterado:
Para um
$lookupque começa com um estágio para uma coleção, por exemplo, um subpipeline$matchou$collStats, você deve incluir o campofrome especificar a coleção.Da mesma forma, para
$unionWith, inclua o campocolle especifique a coleção.
Restrições
Restrições | Descrição |
|---|---|
Um pipeline de agregação não pode utilizar | |
O pipeline $unionWith não pode incluir o estágio | |
O pipeline $unionWith não pode incluir o estágio |
Exemplos
Os exemplos nesta página usam dados do conjunto de dados sample_mflix. Para obter detalhes sobre como carregar este conjunto de dados em sua implantação do MongoDB autogerenciado, consulte Carregar o conjunto de dados de amostra. Se você fez alguma modificação nos bancos de dados de amostra, talvez seja necessário descartar e recriar os bancos de dados para executar os exemplos nesta página.
Criar relatórios de filmes a partir da união de dados de filmes
Os exemplos a seguir usam o estágio $unionWith para combinar data e retornar resultados da coleção movies.
Relatório 1: todos os filmes por categoria e ano
A seguinte agregação cria um relatório de filmes que lista os filmes por categoria. O pipeline usa $unionWith para combinar documentos da coleção movies:
db.movies.aggregate( [ { $match: { year: { $lt: 1910 } } }, { $set: { category: "Early Cinema" } }, { $unionWith: { coll: "movies", pipeline: [ { $match: { runtime: { $gt: 1000 } } }, { $set: { category: "Long Runtime" } } ] } }, { $project: { title: 1, year: 1, category: 1, _id: 0 } }, { $sort: { category: 1, year: 1, title: 1 } }] )[ { title: 'The Kiss', year: 1896, category: 'Early Cinema' }, { title: 'The Kiss', year: 1896, category: 'Early Cinema' }, { title: 'The Great Train Robbery', year: 1903, category: 'Early Cinema' }, { title: 'A Corner in Wheat', year: 1909, category: 'Early Cinema' }, { title: 'Centennial', year: 1978, category: 'Long Runtime' }, { title: 'Baseball', year: 1994, category: 'Long Runtime' }]Especificamente, o aggregation pipeline usa:
Um estágio
$matchpara selecionar filmes lançados antes de1910.Um estágio
$setpara adicionar um campocategorycom o valorEarly Cinema.Um estágio
$unionWithpara combinar documentos da coleçãomovies, filtrados para filmes com umruntimemaior que1000e com a tag da categoriaLong Runtime.Um estágio
$projectpara retornar apenas os campostitle,yearecategory.Um estágio
$sortpara classificar pelocategory,yearetitle.
Relatório 2: Tempo de execução agregado por gênero
A seguinte agregação cria um relatório de filmes que lista o tempo de execução total por gênero. O pipeline usa $unionWith para combinar documentos da coleção movies:
db.movies.aggregate( [ { $match: { year: { $lt: 1910 } } }, { $unionWith: { coll: "movies", pipeline: [ { $match: { runtime: { $gt: 1000 } } } ] } }, { $group: { _id: "$genres", totalRuntime: { $sum: "$runtime" } } }, { $sort: { totalRuntime: -1 } }] )[ { _id: [ 'Action', 'Adventure', 'Drama' ], totalRuntime: 1256 }, { _id: [ 'Documentary', 'History', 'Sport' ], totalRuntime: 1140 }, { _id: [ 'Short', 'Drama' ], totalRuntime: 14 }, { _id: [ 'Short', 'Western' ], totalRuntime: 11 }, { _id: [ 'Short', 'Romance' ], totalRuntime: 2 }]Os estágios
$matche$unionWithrecuperam documentos da coleçãomoviespara o pipeline.O estágio
$sortordena os documentostotalRuntimeem ordem decrescente.
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.
A seguinte operação $unionWith executa uma união com documentos especificados no campo pipeline $documents :
db.movies.aggregate( [ { $match: { runtime: { $gt: 1000 } } }, { $project: { title: 1, year: 1, _id: 0 } }, { $unionWith: { pipeline: [ { $documents: [ { title: "Movie A", year: 2000 }, { title: "Movie B", year: 2001 } ] } ] } }] )[ { title: 'Centennial', year: 1978 }, { title: 'Baseball', year: 1994 }, { title: 'Movie A', year: 2000 }, { title: 'Movie B', year: 2001 }]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:
[BsonIgnoreExtraElements]public class Movie{ [BsonId] public ObjectId Id { get; set; } [BsonElement("title")] public string Title { get; set; } = null!; [BsonElement("year")] public int? Year { get; set; } [BsonElement("runtime")] public int? Runtime { get; set; } [BsonElement("rated")] public string? Rated { get; set; } [BsonElement("metacritic")] public int Metacritic { get; set; } [BsonElement("plot")] public string? Plot { get; set; } [BsonElement("type")] public string? Type { get; set; } [BsonElement("cast")] public string[]? Cast { get; set; } [BsonElement("directors")] public string[]? Directors { get; set; } [BsonElement("writers")] public string[]? Writers { get; set; } [BsonElement("imdb")] public ImdbData? Imdb { get; set; }}Para usar o driver MongoDB .NET/C# para adicionar um estágio $unionWith a uma agregação pipeline, chame o método UnionWith() em um objeto PipelineDefinition.
O exemplo a seguir cria um estágio de pipeline que combina filmes com uma pontuação Metacritic de 100 da coleção sample_mflix.movies com filmes que correspondem aos mesmos critérios:
var pipeline = new EmptyPipelineDefinition<Movie>() .Match(Builders<Movie>.Filter.Eq(m => m.Metacritic, 100)) .UnionWith( withCollection: _movies, withPipeline: new EmptyPipelineDefinition<Movie>() .Match(Builders<Movie>.Filter.Eq(m => m.Metacritic, 100)));{ "metacritic" : 100, "title" : "Best Kept Secret" }{ "metacritic" : 100, "title" : "Best Kept Secret" }{ "metacritic" : 100, "title" : "Boyhood" }{ "metacritic" : 100, "title" : "Boyhood" }{ "metacritic" : 100, "title" : "Fanny and Alexander" }{ "metacritic" : 100, "title" : "Fanny and Alexander" }{ "metacritic" : 100, "title" : "Lawrence of Arabia" }{ "metacritic" : 100, "title" : "Lawrence of Arabia" }{ "metacritic" : 100, "title" : "The Conformist" }{ "metacritic" : 100, "title" : "The Conformist" }{ "metacritic" : 100, "title" : "The Godfather" }{ "metacritic" : 100, "title" : "The Godfather" }{ "metacritic" : 100, "title" : "The Leopard" }{ "metacritic" : 100, "title" : "The Leopard" }{ "metacritic" : 100, "title" : "The Wizard of Oz" }{ "metacritic" : 100, "title" : "The Wizard of Oz" }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;