Docs Menu
Docs Home
/ /

$unionWith (etapa de agregación)

$unionWith

Combina dos agregaciones en un único conjunto de resultados. $unionWith produce el conjunto combinado de resultados (incluidos los duplicados) a la siguiente etapa.

El orden en el que se generan los documentos del conjunto de resultados combinado no está especificado.

La etapa $unionWith tiene la siguiente sintaxis:

{ $unionWith: { coll: "<collection>", pipeline: [ <stage1>, ... ] } }

Para incluir todos los documentos de la colección especificada sin ningún procesamiento, puede utilizar la forma simplificada:

{ $unionWith: "<collection>" } // Include all documents from the specified collection

La etapa $unionWith procesa un documento con los siguientes campos:

Campo
Necesidad
Descripción

coll

Requerido si se omite pipeline. De lo contrario, opcional.

La colección o vista cuyos resultados del pipeline se desean incluir en el conjunto de resultados.

Si omite el campo coll, debe especificar un campo pipeline con una primera etapa de $documents.

Requerido si se omite coll. De lo contrario, opcional.

Una canalización de agregación para aplicar a los documentos de entrada.

  • Si especificas coll, el pipeline se aplica a los documentos en coll.

  • Si omites coll, la pipeline se aplica a los documentos en la etapa $documents de la pipeline. Para ver un ejemplo, consulta Crear una Unión con Documentos Especificados.

La pipeline no puede incluir las etapas $out y $merge. A partir de la versión v6.0, el pipeline puede contener el Búsqueda de Atlas $search etapa como la primera etapa dentro de la pipeline. Para aprender más, consulta Soporte de Atlas Search.

La $unionWith operación correspondería a la siguiente instrucción SQL:

SELECT *
FROM Collection1
WHERE ...
UNION ALL
SELECT *
FROM Collection2
WHERE ...

Los resultados combinados de la etapa anterior y la etapa$unionWith pueden incluir duplicados.

Por ejemplo, crea una colección suppliers y una colección 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" },
])

La siguiente agregación combina los resultados de la proyección del campo state de las colecciones suppliers y warehouse.

db.suppliers.aggregate([
{ $project: { state: 1, _id: 0 } },
{ $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} }
])

El conjunto de resultados contiene duplicados:

{ "state" : "Texas" }
{ "state" : "Colorado" }
{ "state" : "Rhode Island" }
{ "state" : "California" }
{ "state" : "Colorado" }
{ "state" : "Florida" }

Para remover los duplicados, se puede incluir una etapa $group para agrupar por el campo state:

db.suppliers.aggregate([
{ $project: { state: 1, _id: 0 } },
{ $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} },
{ $group: { _id: "$state" } }
])

El conjunto de resultados ya no contiene duplicados:

{ "_id" : "California" }
{ "_id" : "Texas" }
{ "_id" : "Florida" }
{ "_id" : "Colorado" }
{ "_id" : "Rhode Island" }

Si el db.collection.aggregate() incluye un documento collation, la operación utiliza esa intercalación y omite cualquier otra intercalación.

Si el db.collection.aggregate() no incluye un documento collation, el método db.collection.aggregate() utiliza la intercalación para la colección/vista de nivel superior en la que se ejecuta el db.collection.aggregate():

  • Si el $unionWith coll es una colección, se ignorará su intercalación.

  • Si el $unionWith coll es una vista, entonces su intercalación debe coincidir con la de la colección o vista de nivel superior. De lo contrario, la operación fallará.

A partir de MongoDB 6.0, puedes especificar la etapa de Atlas Search $search o $searchMeta en la $unionWith pipeline para buscar colecciones en el clúster de Atlas. La $search o la $searchMeta etapa debe ser la primera etapa dentro del pipeline $unionWith.

[{
"$unionWith": {
"coll": <collection-name>,
"pipeline": [{
"$search": {
"<operator>": {
<operator-specification>
}
},
...
}]
}
}]
[{
"$unionWith": {
"coll": <collection-name>,
"pipeline": [{
"$searchMeta": {
"<collector>": {
<collector-specification>
}
},
...
}]
}
}]

Para ver un ejemplo de $unionWith con $search, consulta el tutorial de Atlas Search Ejecuta una Atlas Search $search query usando $unionWith.

Restricciones
Descripción

Una canalización de agregación no puede utilizar $unionWith dentro de transacciones.

La $unionWith pipeline no puede incluir la etapa $out.

La $unionWith pipeline no puede incluir la etapa $merge.

Los siguientes ejemplos utilizan la etapa $unionWith para combinar datos y devolver resultados de múltiples colecciones. En estos ejemplos, cada colección contiene un año de datos de ventas.

  1. Crea una colección sales_2017 con los siguientes 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 }
    ] )
  2. Crea una colección sales_2018 con los siguientes 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 }
    ] )
  3. Crea una colección sales_2019 con los siguientes 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 }
    ] )
  4. Crea una colección sales_2020 con los siguientes 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 }
    ] )

La siguiente agregación crea un informe anual de ventas que enumera todas las ventas por trimestre y por almacenes. El pipeline utiliza $unionWith para combinar documentos de las cuatro colecciones:

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 } }
] )

En concreto, la pipeline de agregación utiliza:

  • Una $set etapa para actualizar el campo _id para que contenga el año.

  • Una secuencia de $unionWith etapas para combinar todos los documentos de las cuatro colecciones, cada una utilizando también la etapa $set en sus documentos.

  • Una $sort etapa para ordenar por el _id (el año), el store y item.

Salida del 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 }

La siguiente agregación crea un informe de ventas que enumera la cantidad de ventas por cada artículo. El pipeline utiliza $unionWith para combinar documentos de los cuatro años:

db.sales_2017.aggregate( [
{ $unionWith: "sales_2018" },
{ $unionWith: "sales_2019" },
{ $unionWith: "sales_2020" },
{ $group: { _id: "$item", total: { $sum: "$quantity" } } },
{ $sort: { total: -1 } }
] )
  • La secuencia de $unionWith etapas Recupera documentos de las colecciones especificadas en el pipeline:

  • La $group etapa agrupa por el campo item y utiliza $sum para calcular la cantidad total de ventas por item.

  • La $sort etapa ordena los documentos por total de forma descendente.

Salida del pipeline:

{ "_id" : "Cookies", "total" : 1720 }
{ "_id" : "Chocolates", "total" : 1250 }
{ "_id" : "Nuts", "total" : 510 }
{ "_id" : "Pie", "total" : 395 }
{ "_id" : "Cheese", "total" : 350 }

Puedes utilizar $unionWith para realizar una unión con los documentos que especifiques en el campo pipeline. Cuando especificas una etapa $documents en el campo pipeline, realizas una unión con documentos que no están almacenados en una colección separada.

Cree una colección cakeFlavors:

db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )

La siguiente operación $unionWith realiza una unión con los documentos especificados en el campo pipeline $documents:

db.cakeFlavors.aggregate( [
{
$unionWith: {
pipeline: [
{
$documents: [
{ _id: 4, flavor: "orange" },
{ _id: 5, flavor: "vanilla", price: 20 }
]
}
]
}
}
] )

Salida:

[
{ _id: 1, flavor: 'chocolate' },
{ _id: 2, flavor: 'strawberry' },
{ _id: 3, flavor: 'cherry' },
{ _id: 4, flavor: 'orange' },
{ _id: 5, flavor: 'vanilla', price: 20 }
]

Los ejemplos de C# en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulta Primeros pasos en la documentación del controlador de MongoDB .NET/C#.

La siguiente clase Movie modela los documentos en la colección 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 utilizar el driver de MongoDB .NET/C# para añadir una etapa $unionWith a una pipeline de agregación, llame a UnionWith() método en un objeto PipelineDefinition.

El siguiente ejemplo crea una etapa de la pipeline que combina películas con una puntuación Metacritic de 100 de la colección sample_mflix.movies con películas que cumplen los mismos criterios:

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" }

Los ejemplos de Node.js en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte Primeros pasos en la documentación del controlador de MongoDB Node.js.

Para utilizar el controlador de MongoDB Node.js para agregar una etapa de $unionWith a una canalización de agregación, utilice el Operador $unionWith en un objeto de canalización.

El siguiente ejemplo crea una etapa de pipeline que combina los documentos entrantes de la colección sample_mflix.movies con los documentos movie de la colección sample_mflix.movies. A continuación, el ejemplo ejecuta la canalización de agregación:

const db = client.db("sample_mflix");
const collection = db.collection("movies");
const pipeline = [{ $unionWith: { coll: "Movies" } }];
const cursor = collection.aggregate(pipeline);
return cursor;

Volver

$sortByCount

En esta página