Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ / /

$unionWith (집계)

이 페이지의 내용

  • 정의
  • 구문
  • 고려 사항
  • 중복 결과
  • $unionWith 샤드 컬렉션
  • 데이터 정렬
  • Atlas Search 지원
  • 제한 사항
  • 예시
  • Union of Yearly Data Collections에서 판매 보고서 만들기
  • 보고서 1: 연도별, 스토어 및 품목별 모든 판매량
  • 보고서 2: 품목별 매출 애그리게이션
  • 지정된 문서로 유니온 만들기
  • 하위 파이프라인의 네임스페이스
$unionWith

버전 8.0에서 변경되었습니다.

두 개의 집계를 단일 결과 집합으로 결합합니다. $unionWith은 결합된 결과 세트(중복 항목 포함)를 다음 단계로 출력합니다.

결합된 결과 집합 문서가 출력되는 순서는 지정되지 않습니다.

$unionWith 단계에는 다음과 같은 구문이 있습니다.

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

처리하지 않고 지정된 collection의 모든 문서를 포함하려면 간단한 양식을 사용할 수 있습니다.

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

$unionWith 단계에서는 다음 필드가 있는 문서를 사용합니다.

필드
필요성
설명
coll
pipeline이 생략된 경우 필수입니다. 그렇지 않은 경우 선택 사항입니다.

결과 집합에 포함하려는 파이프라인 결과가 있는 collection 또는 보기입니다.

coll 필드를 생략하는 경우 $documents의 첫 번째 단계로 pipeline 필드를 지정해야 합니다.

coll이 생략된 경우 필수입니다. 그렇지 않은 경우 선택 사항입니다.

입력 문서에 적용할 집계 파이프라인입니다.

  • coll을 지정하면 파이프라인은 coll의 문서에 적용됩니다.

  • coll을 생략하면 파이프라인의 $documents 단계에 있는 문서에 파이프라인이 적용됩니다. 예시를 보려면 지정된 문서로 유니온 생성을 참조하세요.

파이프라인에 $out$merge 단계를 포함할 수 없습니다. v6.0부터 pipeline에는 파이프라인 내부의 첫 번째 단계로 Atlas Search $search 단계가 포함될 수 있습니다. 자세히 알아보려면 Atlas Search 지원을 참조하세요.

$unionWith 작업은 다음 SQL 문에 해당합니다.

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

이전 단계와 $unionWith 단계의 결과를 합친 결과에는 중복이 포함될 수 있습니다.

예를 들어 suppliers collection과 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" },
])

다음 집계는 supplierswarehouse collection의 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 collection인 경우 해당 콜레이션은 무시됩니다.

  • $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 $search 쿼리 실행하기를 참조하세요.

제한 사항
설명
집계 파이프라인은 트랜잭션 내에서 $unionWith를 사용할 수 없습니다.
샤딩된 Collection
$unionWith 단계가 $lookup 파이프라인의 일부인 경우 $unionWith coll을 샤딩할 수 없습니다.
$unionWith 파이프라인$out 단계를 포함할 수 없습니다.
$unionWith 파이프라인$merge 단계를 포함할 수 없습니다.

다음 예시에서는 $unionWith 단계를 사용하여 collection을 결합하고 여러 컬렉션의 결과를 반환합니다. 이 예시에서 각 collection에는 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을 사용하여 모두의 컬렉션의 문서를 결합합니다.

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

특히 집계 파이프라인은 다음을 사용합니다.

  • 연도를 포함하도록 _id 필드를 업데이트하는 $set 단계.

  • 4개의 컬렉션에서 모든 문서를 결합하는 일련의 $unionWith 단계로, 각 컬렉션은 해당 문서의 $set 단계도 사용합니다.

  • _id(연도),storeitem 를 기준으로 정렬하는 $sort단계.

파이프라인 출력:

{ "_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부터 $lookup$unionWith 내의 서브파이프라인의 네임스페이스가 fromcoll 필드의 올바른 사용을 보장하기 위해 검증됩니다.

  • $lookup의 경우 지정된 컬렉션이 필요하지 않은 단계를 사용하는 서브파이프라인을 사용할 때는 from 필드를 생략합니다. 예를 들어 $documents 단계입니다.

  • 마찬가지로, $unionWith의 경우 coll 필드를 생략합니다.

변경되지 않은 동작:

  • 예를 들어 $match 또는 $collStats서브파이프라인과 같이 컬렉션을 위한 단계로 시작하는 $lookup의 경우 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