Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

$unionWith (etapa de agregación)

$unionWith

Cambiado en la versión 8.0.

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

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

The collection or view whose pipeline results you wish to include in the result set.

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.

  • If you omit coll, the pipeline applies to the documents in the pipeline's $documents stage. For an example, see Create a Union with Specified Documents.

La canalización no puede incluir las etapas y. A partir de $out $merge la6.0 versión, la etapa pipeline puede contener la etapa de MongoDB Search $search como la primera etapa dentro de la canalización. Para obtener más información, consulte la sección de compatibilidad con MongoDB Search.

The $unionWith operation would correspond to the following SQL statement:

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

The combined results from the previous stage and the $unionWith stage can include duplicates.

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 puede especificar la etapa MongoDB Search $search o en $searchMeta la $unionWith canalización para buscar colecciones en el clúster Atlas. La $search etapa o debe ser la primera etapa dentro de la $searchMeta $unionWith canalización.

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

To see an example of $unionWith with $search, see the MongoDB Search tutorial Run a MongoDB Search $search Query Using $unionWith.

Restricciones
Descripción

An aggregation pipeline cannot use $unionWith inside transactions.

The $unionWith pipeline cannot include the $out stage.

The $unionWith pipeline cannot include the $merge stage.

The following examples use the $unionWith stage to combine data and return results from multiple collections. In these examples, each collection contains a year of sales data.

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

The following aggregation creates a yearly sales report that lists all sales by quarter and stores. The pipeline uses $unionWith to combine documents from all four collections:

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.

  • A sequence of $unionWith stages to combine all documents from the four collections, each also using the $set stage on its documents.

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

The following aggregation creates a sales report that lists the sales quantity per item. The pipeline uses $unionWith to combine documents from all four years:

db.sales_2017.aggregate( [
{ $unionWith: "sales_2018" },
{ $unionWith: "sales_2019" },
{ $unionWith: "sales_2020" },
{ $group: { _id: "$item", total: { $sum: "$quantity" } } },
{ $sort: { total: -1 } }
] )
  • The sequence of $unionWith stages retrieve documents from the specified collections into the 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 }
]

A partir de MongoDB 8.0, namespaces en subpipelines dentro de $lookup y $unionWith se validan para asegurar el uso correcto de los campos from y coll:

  • Para $lookup, omite el campo from si utilizas una subpipeline con una etapa que no requiera una colección especificada. Por ejemplo, una etapa $documents.

  • De manera similar, para $unionWith, omite el campo coll.

Comportamiento sin cambio:

  • Para un $lookup que comienza con una etapa para una colección, por ejemplo, una sub-etapa $match o $collStats, debes incluir el campo from y especificar la colección.

  • De manera similar, para $unionWith, incluye el campo coll y especifica la colección.

El siguiente escenario muestra un ejemplo.

Cree una colección cakeFlavors:

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

A partir de MongoDB 8.0, el siguiente ejemplo devuelve un error porque contiene un campo coll no válido:

db.cakeFlavors.aggregate( [ {
$unionWith: {
coll: "cakeFlavors",
pipeline: [ { $documents: [] } ] }
} ] )

En las versiones de MongoDB anteriores a 8.0, se ejecuta el ejemplo anterior.

Para un ejemplo con un campo coll válido, consulta Duplicate Results.

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

To use the MongoDB .NET/C# driver to add a $unionWith stage to an aggregation pipeline, call the UnionWith() method on a PipelineDefinition object.

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;