Definition
Syntax
The $unionWith stage has the following syntax:
{ $unionWith: { coll: "<collection>", pipeline: [ <stage1>, ... ] } } 
To include all documents from the specified collection without any processing, you can use the simplified form:
{ $unionWith: "<collection>" } // Include all documents from the specified collection 
The $unionWith stage takes a document with the following fields:
| Field | Necessity | Description | 
|---|---|---|
| Required if  | The collection or view whose pipeline results you wish to include in the result set. If you omit the  | |
| Required if  | An aggregation pipeline to apply to the input documents. 
 The pipeline cannot include the  | 
The $unionWith operation would correspond to the following SQL statement:
SELECT * FROM Collection1 WHERE ... UNION ALL SELECT * FROM Collection2 WHERE ... 
Considerations
Duplicate Results
The combined results from the previous stage and the $unionWith stage can include duplicates.
For example, create a suppliers collection and a warehouses collection:
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" }, ]) 
The following aggregation combines the state field projection results from the suppliers and warehouse collections.
db.suppliers.aggregate([  { $project: { state: 1, _id: 0 } },  { $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} } ]) 
The result set contains duplicates:
{ "state" : "Texas" } { "state" : "Colorado" } { "state" : "Rhode Island" } { "state" : "California" } { "state" : "Colorado" } { "state" : "Florida" } 
To remove the duplicates, you can include a $group stage to group by the state field:
db.suppliers.aggregate([  { $project: { state: 1, _id: 0 } },  { $unionWith: { coll: "warehouses", pipeline: [ { $project: { state: 1, _id: 0 } } ]} },  { $group: { _id: "$state" } } ]) 
The result set no longer contains duplicates:
 { "_id" : "California" }  { "_id" : "Texas" }  { "_id" : "Florida" }  { "_id" : "Colorado" }  { "_id" : "Rhode Island" } 
$unionWith a Sharded Collection
If the $unionWith stage is part of the pipeline, the $unionWith coll cannot be sharded. For example, in the following aggregation operation, the inventory_q1 collection cannot be sharded:
db.suppliers.aggregate([  {  $lookup: {  from: "warehouses",  let: { order_item: "$item", order_qty: "$ordered" },  pipeline: [  ...  { $unionWith: { coll: "inventory_q1", pipeline: [ ... ] } },  ...  ],  as: "stockdata"  }  } ]) 
Collation
If the db.collection.aggregate() includes a collation, that collation is used for the operation, ignoring any other collations.
If the db.collection.aggregate() does not include a collation, the db.collection.aggregate() method uses the collation for the top-level collection/view on which the db.collection.aggregate() is run:
- If the $unionWith coll is a collection, its collation is ignored. 
- If the $unionWith coll is a view, then its collation must match that of the top-level collection/view. Otherwise, the operation errors. 
Atlas Search Support
Starting in MongoDB 6.0, you can specify the Atlas Search $search or $searchMeta stage in the $unionWith pipeline to search collections on the Atlas cluster. The $search or the $searchMeta stage must be the first stage inside the $unionWith pipeline.
To see an example of $unionWith with $search, see the Atlas Search tutorial Run an Atlas Search $search Query Using $unionWith.
Restrictions
| Restrictions | Description | 
|---|---|
| An aggregation pipeline cannot use  | |
| Sharded Collection | If the  | 
| The $unionWith pipeline cannot include the  | |
| The $unionWith pipeline cannot include the  | 
Examples
Create Sales Reports from the Union of Yearly Data Collections
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.
Populate Sample Data
- Create a - sales_2017collection with the following documents:- 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 } - ] ) 
- Create a - sales_2018collection with the following documents:- 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 } - ] ) 
- Create a - sales_2019collection with the following documents:- 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 } - ] ) 
- Create a - sales_2020collection with the following documents:- 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 } - ] ) 
Report 1: All Sales by Year and Stores and Items
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 } } ] ) 
Specifically, the aggregation pipeline uses:
- A - $setstage to update the- _idfield to contain the year.
- A sequence of - $unionWithstages to combine all documents from the four collections, each also using the- $setstage on its documents.
- A - $sortstage to sort by the- _id(the year), the- store, and- item.
Pipeline output:
{ "_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 } 
Report 2: Aggregated Sales by Items
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 - $unionWithstages retrieve documents from the specified collections into the pipeline:
- The - $groupstage groups by the- itemfield and uses- $sumto calculate the total sales quantity per- item.
- The - $sortstage orders the documents by descending- total.
Pipeline output:
{ "_id" : "Cookies", "total" : 1720 } { "_id" : "Chocolates", "total" : 1250 } { "_id" : "Nuts", "total" : 510 } { "_id" : "Pie", "total" : 395 } { "_id" : "Cheese", "total" : 350 } 
Create a Union with Specified Documents
You can use $unionWith to perform a union with documents that you specify in the pipeline field. When you specify a $documents stage in the pipeline field, you perform a union with documents that aren't stored in a separate collection.
Create a collection cakeFlavors:
db.cakeFlavors.insertMany( [  { _id: 1, flavor: "chocolate" },  { _id: 2, flavor: "strawberry" },  { _id: 3, flavor: "cherry" } ] ) 
The following $unionWith operation performs a union with documents specified in the pipeline $documents field:
db.cakeFlavors.aggregate( [  {  $unionWith: {  pipeline: [  {  $documents: [  { _id: 4, flavor: "orange" },  { _id: 5, flavor: "vanilla", price: 20 }  ]  }  ]  }  } ] ) 
Output:
[  { _id: 1, flavor: 'chocolate' },  { _id: 2, flavor: 'strawberry' },  { _id: 3, flavor: 'cherry' },  { _id: 4, flavor: 'orange' },  { _id: 5, flavor: 'vanilla', price: 20 } ] 
The C# examples on this page use the sample_mflix database from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB .NET/C# Driver documentation.
The following Movie class models the documents in the sample_mflix.movies collection:
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; } } 
Note
ConventionPack for Pascal Case
The C# classes on this page use Pascal case for their property names, but the field names in the MongoDB collection use camel case. To account for this difference, you can use the following code to register a ConventionPack when your application starts:
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true); 
To use the MongoDB .NET/C# driver to add a $unionWith stage to an aggregation pipeline, call the UnionWith() method on a PipelineDefinition object.
The following example creates a pipeline stage that combines the incoming documents from the sample_mflix.movies collection with the Movie documents in the sample_mflix.Movies collection:
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);  
The Node.js examples on this page use the sample_mflix database from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB Node.js driver documentation.
To use the MongoDB Node.js driver to add a $unionWith stage to an aggregation pipeline, use the $unionWith operator in a pipeline object.
The following example creates a pipeline stage that combines the incoming documents from the sample_mflix.movies collection with the movie documents in the sample_mflix.Movies collection. The example then runs the aggregation pipeline:
const db = client.db("sample_mflix"); const collection = db.collection("movies"); const pipeline = [{ $unionWith: { coll: "Movies" } }]; const cursor = collection.aggregate(pipeline); return cursor;