Docs Menu
Docs Home
/
MongoDBマニュアル
/ / /

$unionWith(集計)

項目一覧

  • 定義
  • 構文
  • Considerations
  • 重複した結果
  • $unionWith シャーディングされたコレクション
  • 照合
  • Atlas Search サポート
  • 制限事項
  • 年間データ コレクションの和集合から売上レポートを作成
  • レポート 1: 年別、店舗別、商品別全売上
  • レポート 2: 品目別売上集計
  • 指定されたドキュメントとの Union の作成
  • サブパイプラインの名前空間
$unionWith

バージョン8.0で変更

2 つの集計を 1 つの結果セットに結合します。 $unionWithは結合された結果セット(重複を含む)を次のステージに出力します。

結合された結果セットのドキュメントが出力される順序は指定されていません。

$unionWith ステージの構文は次のとおりです。

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

指定したコレクションの全ドキュメントを処理せずに含めるには、簡略化された形式を使用できます。

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

$unionWithステージは、次のフィールドを持つドキュメントを取得します。

フィールド
必要性
説明
coll
pipeline を省略する場合は必須です。それ以外は任意です。

結果セットに含めるパイプラインの結果のコレクションまたはビュー。

collフィールドを省略する場合は、 $documentsの最初のステージを持つpipelineフィールドを指定する必要があります。

coll を省略する場合は必須です。それ以外は任意です。

入力ドキュメントに適用する集計パイプライン。

  • collを指定すると、パイプラインはcollのドキュメントに適用されます。

  • coll を省略すると、パイプラインはパイプライン内の $documents ステージのドキュメントに適用されます。例えについては、「指定されたドキュメントとの Union の作成」を参照してください。

パイプラインには $out ステージと $merge ステージを含めることはできません。v6.0 以降では、 pipeline にはパイプライン内の最初のステージとして Atlas Search $search ステージを含めることができます。詳しくは「Atlas Search サポート」を参照してください。

$unionWith操作は、次の SQL ステートメントに対応します。

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

前のステージと $unionWith ステージから組み合わせた結果には重複が含まれる場合があります。

たとえば、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" },
])

次の集計は、suppliers コレクションと warehouse コレクションの state フィールドのプロジェクション結果を組み合わせたものです。

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

結果セットには重複が含まれています。

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

重複を削除するには、$group ステージを追加して、state フィールドでグループ化します。

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

結果セットには重複が含まれなくなりました。

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

$unionWith ステージが $lookup パイプラインの一部である場合、$unionWith coll はシャーディングできません。たとえば、次の集計操作では、inventory_q1 コレクションをシャーディングできません。

db.suppliers.aggregate([
{
$lookup: {
from: "warehouses",
let: { order_item: "$item", order_qty: "$ordered" },
pipeline: [
...
{ $unionWith: { coll: "inventory_q1", pipeline: [ ... ] } },
...
],
as: "stockdata"
}
}
])

db.collection.aggregate()collationドキュメントが含まれている場合、その照合が操作に使用され、他の照合は無視されます。

db.collection.aggregate()collationドキュメントが含まれていない場合、 db.collection.aggregate()メソッドは、 db.collection.aggregate()が実行される最上位のコレクションやビューの照合を使用します。

  • $unionWith coll がコレクションの場合、その照合は無視されます。

  • $unionWith collビューの場合、その照合は最上位のコレクションやビューの照合と一致する必要があります。そうでない場合はエラーとなります。

MongoDB 6.0 以降では、 $unionWith パイプラインで Atlas Search $search または $searchMeta ステージを指定して、Atlas クラスター上のコレクションを検索できます。$search または $searchMeta ステージは、 $unionWith パイプライン内の最初のステージである必要があります。

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

$searchとともに$unionWithを使用した例えについては、Atlas Search チュートリアルの「$unionWith を使用して Atlas Search $検索クエリを実行する」を参照してください。

制限事項
説明
集計パイプラインでは、 トランザクション$unionWith 内で を使用できません。
シャーディングされたコレクション
$unionWithステージが$lookup パイプラインの一部である場合、 $unionWith collはシャーディングできません。
$unionWith パイプラインには$outステージを含めることはできません。
$unionWith パイプラインには$mergeステージを含めることはできません。

次の例では、$unionWith ステージを使用してデータを結合し、複数のコレクションから結果を返します。これらの例では、各コレクションに 1 年間の販売データが含まれています。

  1. 次のドキュメントを使用して 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 }
    ] )
  2. 次のドキュメントを使用して 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 }
    ] )
  3. 次のドキュメントを使用して 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 }
    ] )
  4. 次のドキュメントを使用して 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 }
    ] )

次の集計では、四半期および店舗ごとのすべての売上を一覧表示する年間売上レポートが作成されます。 パイプラインは$unionWithを使用して次の 4 つのすべてのコレクションのドキュメントを結合します。

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

具体的には、集計パイプラインでは次のものが使用されます。

  • $set ステージで、_id フィールドを更新して年を含めます。

  • 4 つのコレクションのすべてのドキュメントを結合するための$unionWithステージのシーケンス。それぞれのドキュメントで$setステージも使用します。

  • $sort ステージで、_id(年)、storeitem で並べ替えます。

パイプライン出力は次のようになります。

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

次の集計では、品目ごとの販売数量を一覧表示する販売レポートが作成されます。パイプラインは $unionWith を使用して 4 年間すべてのドキュメントを結合します。

db.sales_2017.aggregate( [
{ $unionWith: "sales_2018" },
{ $unionWith: "sales_2019" },
{ $unionWith: "sales_2020" },
{ $group: { _id: "$item", total: { $sum: "$quantity" } } },
{ $sort: { total: -1 } }
] )
  • $unionWithステージのシーケンスは、指定されたコレクションからパイプラインにドキュメントを検索します。

  • $group ステージは item フィールドでグループ化し、$sum を使用して item ごとの合計販売数量を計算します。

  • $sort ステージでは、ドキュメントを total の降順で並べ替えます。

パイプライン出力は次のようになります。

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

$unionWithを使用して、 pipelineフィールドに指定したドキュメントとの和集合を実行できます。 pipelineフィールドに$documentsステージを指定すると、別のコレクションに保存されていないドキュメントとの和集合が実行されます。

コレクション cakeFlavors を以下ように作成します。

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

次の$unionWith操作は、 pipeline $documentsフィールドに指定されたドキュメントとの和集合を実行します。

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

出力:

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

MongoDB 8.0 以降では、from フィールドと coll フィールドが正しく使用されるように、$lookup$unionWith 内のサブパイプラインの名前空間が検証されます。

  • $lookup の場合、指定されたコレクションを必要としないステージを持つサブパイプラインを使用する場合は、from フィールドを省略する(例: $documents ステージ)。

  • 同様に、$unionWith の場合、coll フィールドを省略する。

変更されていない動作:

  • コレクションのステージで開始される $lookup の場合(例: $match サブパイプラインまたは $collStats サブパイプライン)、from フィールドを含め、コレクションを指定する必要があります。

  • 同様に、$unionWith の場合は、coll フィールドを含め、コレクションを指定します。

次のシナリオは例です。

コレクション cakeFlavors を以下ように作成します。

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

MongoDB 8.0 以降、次の例では、無効な coll フィールドが含まれているためエラーが返されます。

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

8.0 より前の MongoDB バージョンでは、前の例が実行されます。

有効な coll フィールドの例については、「重複した結果」を参照してください。

戻る

$sortByCount