$unionWith (aggregation)
On this page本页内容
Definition定义Syntax语法Considerations注意事项Duplicate Results重复的结果$unionWith
a Sharded Collection分片集合Collation排序规则Atlas Search SupportAtlas搜索支持Restrictions限制Examples实例Create Sales Reports from the Union of Yearly Data Collections从年度数据集合联盟创建销售报告Report 1: All Sales by Year and Stores and Items报告1:按年份、商店和项目列出的所有销售额Report 2: Aggregated Sales by Items报告2:按项目汇总的销售额
Definition定义
$unionWith
New in version 4.4.4.4版新增。Performs a union of two collections.执行两个集合的并集。$unionWith
combines pipeline results from two collections into a single result set.$unionWith
将来自两个集合的管道结果组合为一个结果集。The stage outputs the combined result set (including duplicates) to the next stage.该阶段将组合的结果集(包括重复项)输出到下一阶段。The order in which the combined result set documents are output is unspecified.未指定组合结果集文档的输出顺序。
Syntax语法
The $unionWith
stage has the following syntax:$unionWith
阶段具有以下语法:
{ $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:$unionWith
阶段接受一个包含以下字段的文档:
coll | |
pipeline | coll 的聚合管道。[ <stage1>, <stage2>, ...] $out and $merge stages. $out 和$merge 阶段。pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. pipeline 可以包含Atlas Search$Search 阶段作为管道内的第一个阶段。 |
The $unionWith
operation would correspond to the following SQL statement:$unionWith
操作将对应于以下SQL语句:
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.$unionWith
阶段的组合结果可能包括重复项。
For example, create a 例如,创建suppliers
collection and a warehouses
collection:suppliers
集合和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" },
])
The following aggregation combines the 以下聚合组合了来自state
field projection results from the suppliers
and warehouse
collections.suppliers
和warehouse
集合的state
字段投影结果。
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:$group
阶段以按state
字段分组:
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 $lookup pipeline, the $unionWith
coll cannot be sharded. $unionWith
阶段是$lookup
pipeline
的一部分,则不能对$unionWith
coll
进行分片。For example, in the following aggregation operation, the 例如,在以下聚合操作中,inventory_q1
collection cannot be sharded:inventory_q1
集合无法进行分片:
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.db.collection.aggregate()
包含collation
,则该排序规则将用于操作,而忽略任何其他排序规则。
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:db.collection.aggregate()
不包括collation
,则db.collection.aggregate()
方法将使用运行db.collection.aggregate()
的顶级集合/视图的排序规则:
If the $unionWith coll is a collection, its collation is ignored.如果$unionWith
coll
是一个集合,则会忽略其排序规则。If the $unionWith coll is a view, then its collation must match that of the top-level collection/view. Otherwise, the operation errors.如果$unionWith
coll
是一个视图,则其排序规则必须与顶级集合/视图的排序规则匹配。否则,操作将出错。
Atlas Search SupportAtlas搜索支持
Starting in MongoDB 6.0, you can specify the Atlas Search 从MongoDB 6.0开始,您可以在$search
or $searchMeta
stage in the $unionWith
pipeline to search collections on the Atlas cluster. $unionWith
管道中指定Atlas Search $search
或$searchMeta
阶段来搜索Atlas集群上的集合。The $search
or the $searchMeta
stage must be the first stage inside the $unionWith
pipeline.$search
或$searchMeta
阶段必须是$unionWith
管道内的第一个阶段。
[{
"$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 Atlas Search tutorial Run an Atlas Search $search Query Using $unionWith.$unionWith
与$search
的示例,请参阅Atlas search教程使用$unionwith
运行Atlas search $search
查询。
Restrictions限制
$unionWith inside transactions.$unionWith 。 | |
$unionWith stage is part of the $lookup pipeline, the $unionWith coll cannot be sharded.$unionWith 阶段是$lookup pipeline 的一部分,则不能对$unionWith coll 进行分片。 | |
$out | $out stage.$unionWith pipeline 不能包括$out 阶段。 |
$merge | $merge stage.$unionWith pipeline 不能包含$merge 阶段。 |
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.$unionWith
阶段组合数据并返回多个集合的结果。在这些示例中,每个集合都包含一年的销售数据。
Populate Sample Data填充示例数据
Create a使用以下文档创建sales_2017
collection with the following documents:sales_2017
集合: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_2018
collection with the following documents:sales_2018
集合: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_2019
collection with the following documents:sales_2019
集合: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_2020
collection with the following documents:sales_2020
集合: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报告1:按年份、商店和项目列出的所有销售额
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:$unionWith
组合来自所有四个集合的文档:
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一个$set
stage to update the_id
field to contain the year.$set
阶段,用于更新_id
字段以包含年份。A sequence of一个$unionWith
stages to combine all documents from the four collections, each also using the$set
stage on its documents.$unionWith
阶段的序列,用于组合四个集合中的所有文档,每个集合还在其文档上使用$set
阶段。A一个$sort
stage to sort by the_id
(the year), thestore
, anditem
.$sort
阶段,用于根据_id
(年份)、store
和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报告2:按项目汇总的销售额
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:$unionWith
组合所有四年的文档:
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:$unionWith
阶段的序列将指定集合中的文档检索到管道中:The$group
stage groups by theitem
field and uses$sum
to calculate the total sales quantity peritem
.$group
阶段按item
字段分组,并使用$sum
计算每个物料的总销售数量。The$sort
stage orders the documents by descendingtotal
.$sort
阶段按total
降序排列文档。
Pipeline output:管道输出:
{ "_id" : "Cookies", "total" : 1720 }
{ "_id" : "Chocolates", "total" : 1250 }
{ "_id" : "Nuts", "total" : 510 }
{ "_id" : "Pie", "total" : 395 }
{ "_id" : "Cheese", "total" : 350 }