AI 에이전트의 경우: 문서 인덱스는 https://www.mongodb.com/ko-kr/docs/llms.txt에서 사용할 수 있으며, 모든 페이지의 마크다운 버전은 어떤 URL 경로에 .md를 추가하여 사용할 수 있습니다.
Docs Menu

$merge (집계 단계)

참고

이 페이지에서는 집계 파이프라인 결과를 컬렉션으로 출력하는 $merge 단계를 설명합니다. 문서를 단일 문서로 병합하는 $mergeObjects 연산자에 대해서는 $mergeObjects를 참조하세요.

$merge

집계 파이프라인의 결과를 지정된 컬렉션에 씁니다. $merge 연산자는 반드시 파이프라인의 마지막 단계여야 합니다.

다음은 $merge 단계입니다.

  • 동일하거나 다른 데이터베이스의 컬렉션으로 출력할 수 있습니다.

  • 집계 중인 동일한 컬렉션으로 출력할 수 있습니다. 자세한 내용은 집계 중인 동일한 컬렉션에 출력하기를 참조하세요.

  • 집계 파이프라인에서 $merge 또는 $out 단계를 사용할 때 다음 사항을 고려하세요.

    • MongoDB 5.0부터 $merge 단계가 있는 파이프라인은 클러스터의 모든 노드에서 featureCompatibilityVersion5.0 이상으로 설정되어 있고 읽기 설정이 세컨더리 읽기를 허용하는 경우 복제본 세트 세컨더리 노드에서 실행될 수 있습니다.

      • $merge $out 단계는 세컨더리 노드에서 실행되지만 쓰기 작업은 프라이머리 노드로 전송됩니다.

      • 모든 드라이버 버전이 보조 노드로 전송되는 $merge 연산을 지원하는 것은 아닙니다. 자세한 내용은 드라이버 설명서를 참조하세요.

    • 이전 MongoDB 버전에서는 $out 또는 $merge 단계가 있는 파이프라인은 항상 기본 노드에서 실행되며 읽기 기본 설정은 고려되지 않았습니다.

  • 출력 컬렉션이 아직 존재하지 않는 경우 새 컬렉션을 생성합니다.

  • 결과(새 문서 삽입, 문서 병합, 문서 교체, 기존 문서 유지, 작업 실패, 사용자 지정 업데이트 파이프라인으로 문서 처리)를 기존 컬렉션에 통합할 수 있습니다.

  • 샤드된 컬렉션으로 출력할 수 있습니다. 입력 컬렉션도 샤딩할 수 있습니다.

집계 결과를 컬렉션으로 출력하는 $out 단계와 비교하려면 $merge$out 비교를 참조하세요.

참고

온디맨드 구체화된 보기

$merge 컬렉션을 완전히 교체하는 대신 파이프라인 결과를 기존 출력 컬렉션에 통합할 수 있습니다. 이 기능을 사용하면 파이프라인이 실행될 때 출력 컬렉션의 콘텐츠가 점진적으로 업데이트되는 온디맨드 구체화된 보기를 만들 수 있습니다.

이 사용 사례에 대한 자세한 내용은 이 페이지의 예시 및 온디맨드 구체화된 뷰를 참조하세요.

구체화된 보기는 읽기 전용 보기와 별개입니다. 읽기 전용 보기를 만드는 방법에 대한 자세한 내용은 읽기 전용 보기를 참조하십시오.

다음 환경에서 호스팅되는 배포에 $merge 사용할 수 있습니다.

  • MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스

$merge 의 구문은 다음과 같습니다:

{ $merge: {
into: <collection> -or- { db: <db>, coll: <collection> },
on: <identifier field> -or- [ <identifier field1>, ...], // Optional
let: <variables>, // Optional
whenMatched: <replace|keepExisting|merge|fail|pipeline>, // Optional
whenNotMatched: <insert|discard|fail> // Optional
} }

예를 들면 다음과 같습니다.

{ $merge: { into: "myOutput", on: "_id", whenMatched: "replace", whenNotMatched: "insert" } }

동일한 데이터베이스의 컬렉션에 쓰는 것을 포함하여 $merge에 대한 모든 기본 옵션을 사용하는 경우 간소화된 양식을 사용할 수 있습니다.

{ $merge: <collection> } // Output collection is in the same database

$merge는 다음 필드가 포함된 문서를 사용합니다.

필드
설명

출력 컬렉션입니다. 다음 중 하나를 지정합니다.

  • 집계가 실행되는 동일한 데이터베이스의 컬렉션에 출력할 문자열인 컬렉션 이름입니다. 예시:

    into: "myOutput"

  • 지정된 데이터베이스의 컬렉션으로 출력할 문서의 데이터베이스 및 컬렉션 이름입니다. 예시:

    into: { db:"myDB", coll:"myOutput" }

출력 컬렉션이 존재하지 않으면 $merge 컬렉션을 생성합니다.

  • 복제본 세트 또는 독립형의 경우 출력 데이터베이스가 없으면 $merge도 데이터베이스를 생성합니다.

  • 샤딩된 클러스터의 경우 지정된 출력 데이터베이스가 이미 존재해야 합니다.

출력 컬렉션은 샤드된 컬렉션일 수 있습니다.

선택 사항입니다. 문서의 고유 식별자 역할을 하는 하나 이상의 필드입니다. 식별자는 결과 문서가 출력 컬렉션의 기존 문서와 일치 여부를 결정합니다. 다음 중 하나를 지정합니다.

  • 단일 필드 이름을 문자열로 입력합니다. 예시:

    on: "_id"

  • 배열의 필드 조합입니다. 예시:

    on: [ "date", "customerId" ]

    배열의 필드 순서는 중요하지 않으며 동일한 필드를 여러 번 지정할 수 없습니다.

지정된 필드에 대해

  • 집계 결과 문서에는 on 필드가 _id 필드가 아닌 한 on에 지정된 필드가 포함되어야 합니다. 결과 문서에서 _id 필드가 누락된 경우, MongoDB가 자동으로 추가합니다.

  • 지정한 필드에 하나 이상의 필드에 널 또는 배열 값을 포함할 수 없습니다.

$merge에는 고유한 인덱스가 필요한데, 이 인덱스는 on 식별자 필드에 해당하는 키가 있어야 합니다. 인덱스 키 지정 순서는 중요하지 않지만 고유 인덱스는 반드시 on 필드만 키로 포함해야 합니다.

  • 또한 인덱스는 집계의 데이터 정렬과 동일한 데이터 정렬을 가져야 합니다.

  • 고유 인덱스는 희소 인덱스일 수 있습니다.

  • 고유 인덱스는 부분 인덱스일 수 없습니다.

  • 이미 존재하는 출력 컬렉션의 경우 해당 인덱스가 이미 존재해야 합니다.

on 기본값은 출력 컬렉션에 따라 다릅니다.

  • 출력 컬렉션이 없으면 on 식별자는 _id 필드여야 하며 기본값은 _id 필드입니다. 해당 고유 _id 인덱스가 자동으로 생성됩니다.

    • 존재하지 않는 컬렉션에 대해 다른 on 식별자 필드를 사용하려면 먼저 원하는 필드에 고유 인덱스를 만들어 컬렉션을 생성할 수 있습니다. 예를 보려면 존재하지 않는 출력 수집 섹션을 참조하세요.
  • 기존 출력 컬렉션이 샤딩 해제된 경우 on 식별자는 기본적으로 _id 필드로 설정됩니다.

  • 기존 출력 컬렉션이 샤드된 컬렉션인 경우 on 식별자는 기본적으로 모든 샤드 키 필드와 _id 필드로 설정됩니다. 다른 on 식별자를 지정하는 경우 on에는 모든 샤드 키 필드가 포함되어야 합니다.

선택 사항입니다. 결과 문서와 컬렉션의 기존 문서가 지정된 on 필드에 대해 동일한 값을 갖는 경우의 $merge 동작입니다.

다음 두 가지 중 하나를 지정할 수 있습니다.

  • 미리 정의된 동작 문자열 중 하나입니다.

    작업
    설명

    출력 컬렉션의 기존 문서를 일치하는 결과 문서로 바꿉니다.

    바꾸기를 수행할 때 대체 문서로 인해 _id 값이 수정될 수 없으며 출력 컬렉션이 샤딩된 경우 샤드 키 값도 수정할 수 없습니다. 그렇지 않으면 작업이 오류를 생성합니다.

    이 오류를 방지하려면 on 필드에 _id 필드가 포함되지 않은 경우 집계 결과에서 _id 필드를 제거하여 이전 $unset 단계 등과 같이 오류를 방지합니다.

    기존 문서는 출력 컬렉션에 그대로 유지합니다.

    "merge"(기본값)

    일치하는 문서를 병합합니다($mergeObjects 연산자와 유사).

    • 결과 문서에 기존 문서에 없는 필드가 포함된 경우 이러한 새 필드를 기존 문서에 추가합니다.

    • 결과 문서에 기존 문서의 필드가 포함된 경우 기존 필드 값을 결과 문서의 값으로 바꿉니다.

    예를 들어 출력 컬렉션에 문서가 있는 경우입니다.

    { _id: 1, a: 1, b: 1 }

    그리고 집계 결과에는 문서가 있습니다.

    { _id: 1, b: 5, z: 1 }

    그러면 병합된 문서가 됩니다.

    { _id: 1, a: 1, b: 5, z: 1 }

    병합을 수행할 때 병합된 문서로 인해 _id 값이 수정될 수 없으며 출력 컬렉션이 샤딩된 경우 샤드 키 값도 수정할 수 없습니다. 그렇지 않으면 작업이 오류를 생성합니다.

    이 오류를 방지하려면 on 필드에 _id 필드가 포함되지 않은 경우 집계 결과에서 _id 필드를 제거하여 이전 $unset 단계 등과 같이 오류를 방지합니다.

    집계 작업을 중지하고 실패합니다. 이전 문서의 출력 컬렉션에 대한 변경 사항은 반환되지 않습니다.

  • 컬렉션의 문서를 업데이트하기 위한 집계 파이프라인입니다.

    [ <stage1>, <stage2> ... ]

    파이프라인은 다음 단계로만 구성될 수 있습니다.

    파이프라인은 on 필드의 값을 수정할 수 없습니다. 예를 들어, month 필드에서 일치하는 경우 파이프라인은 month 필드를 수정할 수 없습니다.

    whenMatched pipeline$<field>를 사용해 출력 컬렉션에 있는 기존 문서의 필드에 직접 액세스할 수 있습니다.

    집계 결과 문서의 필드에 액세스하려면 다음 중 하나를 사용합니다.

    • 필드에 액세스하기 위한 기본 제공 $$new 변수입니다. 구체적으로 $$new.<field>입니다. $$new 변수는 let 지정이 생략된 경우에만 사용할 수 있습니다.

    • let 필드의 사용자 정의 변수입니다.

      변수 이름과 함께 이중 달러 기호 ($$) 접두사를 $$<variable_name> 형식으로 지정합니다. 예시: $$year. 변수가 문서로 설정된 경우 $$<variable_name>.<field> 형식으로 문서 필드를 포함할 수도 있습니다. 예시: $$year.month.

      자세한 예는 변수를 사용하여 병합을 사용자 지정하기를 참조하세요.

선택 사항입니다. whenMatched 파이프라인에서 사용할 변수를 지정합니다.

변수 이름과 값 표현식이 있는 문서를 지정합니다.

{ <variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n> }

지정하지 않은 경우 기본값은 { new: "$$ROOT" } (ROOT 참조)입니다. whenMatched 파이프라인$$new 변수에 액세스할 수 있습니다.

whenMatched 파이프라인의 변수에 액세스하려면 다음을 수행합니다.

변수 이름과 함께 이중 달러 기호 ($$) 접두사를 $$<variable_name> 형식으로 지정합니다. 예시: $$year. 변수가 문서로 설정된 경우 $$<variable_name>.<field> 형식으로 문서 필드를 포함할 수도 있습니다. 예시: $$year.month.

자세한 예는 변수를 사용하여 병합을 사용자 지정하기를 참조하세요.

선택 사항입니다. 결과 문서가 아웃 컬렉션의 기존 문서와 일치하지 않는 경우 $merge의 동작입니다.

미리 정의된 동작 문자열 중 하나를 지정할 수 있습니다:

작업
설명

"insert"(기본값)

문서를 출력 컬렉션에 삽입합니다.

문서를 삭제합니다. 특히 $merge는 문서를 출력 컬렉션에 삽입하지 않습니다.

집계 작업을 중지하고 실패합니다. 출력 컬렉션에 이미 기록된 변경 사항은 반환되지 않습니다.

집계 파이프라인 결과에서 _id 필드가 문서에 없는 경우 $merge 단계에서 자동으로 생성합니다.

예를 들어, 다음 집계 파이프라인에서 $project$merge에 전달된 문서에서 _id 필드를 제외합니다. $merge가 이러한 문서를 "newCollection"에 쓰면 $merge는 새로운 _id 필드와 값을 생성합니다.

db.sales.aggregate( [
{ $project: { _id: 0 } },
{ $merge : { into : "newCollection" } }
] )

지정한 출력 컬렉션이 없는 경우 $merge 작업은 새 컬렉션을 생성합니다.

  • 출력 컬렉션은 $merge가 컬렉션에 첫 번째 문서를 쓸 때 생성되며 즉시 표시됩니다.

  • 집계에 실패하면 오류가 발생하기 전에 $merge가 완료한 모든 쓰기는 롤백되지 않습니다.

참고

복제본 세트 또는 독립형의 경우 출력 데이터베이스가 없으면 $merge도 데이터베이스를 생성합니다.

샤딩된 클러스터의 경우 지정된 출력 데이터베이스가 이미 존재해야 합니다.

출력 컬렉션이 존재하지 않는 경우 $mergeon 식별자가 _id 필드여야 합니다. 존재하지 않는 컬렉션에 다른 on 필드 값을 사용하려면 먼저 원하는 필드에 고유 인덱스를 생성하여 컬렉션을 만들 수 있습니다. 예를 들어 출력 컬렉션 newDailySales201905 가 존재하지 않고 salesDate 필드를 on 식별자로 지정하려는 경우입니다.

db.newDailySales201905.createIndex( { salesDate: 1 }, { unique: true } )
db.sales.aggregate( [
{ $match: { date: { $gte: new Date("2019-05-01"), $lt: new Date("2019-06-01") } } },
{ $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, totalqty: { $sum: "$quantity" } } },
{ $project: { _id: 0, salesDate: { $toDate: "$_id" }, totalqty: 1 } },
{ $merge : { into : "newDailySales201905", on: "salesDate" } }
] )

$merge 단계는 샤딩된 컬렉션으로 출력할 수 있습니다. 출력 컬렉션이 샤딩되면 $merge_id 필드와 모든 샤드 키 필드를 식별자 on의 기본값으로 사용합니다. 기본값을 재정의하는 경우, on 식별자에는 모든 샤드 키 필드가 포함되어야 합니다.

{ $merge: {
into: "<shardedColl>" or { db:"<sharding enabled db>", coll: "<shardedColl>" },
on: [ "<shardkeyfield1>", "<shardkeyfield2>",... ], // Shard key fields and any additional fields
let: <variables>, // Optional
whenMatched: <replace|keepExisting|merge|fail|pipeline>, // Optional
whenNotMatched: <insert|discard|fail> // Optional
} }

예를 들어 sh.shardCollection() 메서드를 사용하여 postcode 필드를 샤드 키로 사용하여 새 샤드된 컬렉션 newrestaurants를 만듭니다.

sh.shardCollection(
"exampledb.newrestaurants", // Namespace of the collection to shard
{ postcode: 1 }, // Shard key
);

newrestaurants 컬렉션에는 월별(date 필드) 및 우편 번호(샤드 키)로 새 레스토랑 개점 정보가 있는 문서가 포함되며, 특히 on 식별자는 ["date", "postcode"]입니다(필드 순서는 중요하지 않음). $merge에는 on 식별자 필드에 해당하는 키가 있는 고유 인덱스가 필요하므로 고유 인덱스를 생성합니다(필드 순서는 중요하지 않음). [1]

use exampledb
db.newrestaurants.createIndex( { postcode: 1, date: 1 }, { unique: true } )

샤드된 컬렉션 restaurants 과 생성된 고유 인덱스를 사용하면 $merge를 사용하여 이 컬렉션에 집계 결과를 출력하고, 이 예시에서처럼 [ "date", "postcode" ]에 일치하는 결과를 출력할 수 있습니다:

use exampledb
db.openings.aggregate([
{ $group: {
_id: { date: { $dateToString: { format: "%Y-%m", date: "$date" } }, postcode: "$postcode" },
restaurants: { $push: "$restaurantName" } } },
{ $project: { _id: 0, postcode: "$_id.postcode", date: "$_id.date", restaurants: 1 } },
{ $merge: { into: "newrestaurants", "on": [ "date", "postcode" ], whenMatched: "replace", whenNotMatched: "insert" } }
])
[1]

sh.shardCollection() 메서드는 { unique: true } 옵션을 전달할 때 샤드 키 에 고유 인덱스 생성할 수도 있습니다. 샤드 키 범위 기반이고, 컬렉션 이 비어 있고, 샤드 키 의 고유 인덱스 아직 존재하지 않는 경우 .

이전 예시 에서는 on 식별자가 샤드 키 와 다른 필드 이므로 해당 인덱스 생성하기 위한 별도의 작업이 필요합니다.

집계 결과에 on 사양에 따라 일치하는 문서가 하나 이상 포함된 경우 $merge는 출력 컬렉션의 기존 문서를 대체할 수 있습니다. 따라서 집계 결과에 컬렉션의 모든 기존 문서에 대해 일치하는 문서가 포함되어 있고 whenMatched'replace'를 지정한 경우 $merge는 기존 컬렉션의 모든 문서를 대체할 수 있습니다.

그러나 집계 결과에 관계없이 기존 컬렉션을 바꾸려면 $out 대신 사용합니다.

$merge$merge 때문에 기존 문서의 _id 값이 변경되면 오류를 발생시킵니다.

이 오류를 방지하려면 on 필드에 _id 필드가 포함되지 않은 경우 집계 결과에서 _id 필드를 제거하여 이전 $unset 단계 등과 같이 오류를 방지합니다.

또한, 샤드된 컬렉션의 경우 $merge는 기존 문서의 샤드 키 값이 변경되는 경우에도 오류를 생성합니다.

오류가 발생하기 전에 $merge가 완료한 모든 쓰기는 롤백되지 않습니다.

on 필드에 대해 $merge가 사용하는 고유 인덱스가 집계 도중에 제거되는 경우 집계가 중단된다는 보장이 없습니다. 집계가 계속되면 문서에 중복된 on 필드 값이 없다는 보장이 없습니다.

$merge가 출력 컬렉션의 고유 인덱스를 위반하는 문서를 작성하려고 하면 작업이 오류를 생성합니다. 예를 들면 다음과 같습니다.

  • 온 필드의 인덱스가 아닌 고유 인덱스를 위반하는 일치하지 않는 문서를 삽입합니다 .

  • 컬렉션에 일치하는 문서가 있으면실패합니다. 즉, 이 작업은 on 필드의 고유 인덱스를 위반하는 일치하는 문서를 삽입하려고 시도합니다.

  • 기존 문서를 on 필드의 인덱스가 아닌 고유 인덱스를 위반하는 새 문서로 바꿉니다.

  • 일치하는 문서를 병합하면 필드의 인덱스가 아닌 고유 인덱스를 위반하는 문서가 생성됩니다.

컬렉션이 스키마 유효성 검사를 사용하고 validationActionerror로 설정된 경우, $merge로 잘못된 문서를 삽입하거나 잘못된 값으로 문서를 업데이트하면 MongoServerError가 발생하며, 문서는 대상 컬렉션에 기록되지 않습니다. 잘못된 문서가 여러 개 있는 경우, 처음으로 발견된 잘못된 문서만 오류를 발생시킵니다. 모든 유효한 문서는 대상 컬렉션에 기록되며 모든 잘못된 문서는 기록에 실패합니다.

$merge 다음 모든 조건이 참일 경우 문서를 출력 컬렉션에 직접 삽입합니다.

  • whenMatched 의 값은 집계 파이프라인입니다.

  • whenNotMatched 의 값은 insert입니다.

  • 출력 컬렉션에 일치하는 문서가 없습니다.

$merge의 도입으로 MongoDB는 집계 파이프라인의 결과를 컬렉션에 기록하기 위해 $merge$out의 두 단계를 제공합니다.

  • 동일하거나 다른 데이터베이스의 컬렉션으로 출력할 수 있습니다.
  • 동일하거나 다른 데이터베이스의 컬렉션으로 출력할 수 있습니다.
  • 출력 컬렉션이 아직 존재하지 않는 경우 새 컬렉션을 생성합니다.
  • 출력 컬렉션이 아직 존재하지 않는 경우 새 컬렉션을 생성합니다.
  • 결과(새 문서 삽입, 문서 병합, 문서 교체, 기존 문서 유지, 작업 실패, 사용자 지정 업데이트 파이프라인으로 문서 처리)를 기존 컬렉션에 통합할 수 있습니다.

    문서 바꾸기($merge) 대 컬렉션 바꾸기($out)도 참조하세요.

  • 출력 컬렉션이 이미 있는 경우 완전히 바꿉니다.
  • 샤드된 컬렉션으로 출력할 수 있습니다. 입력 컬렉션도 샤딩할 수 있습니다.
  • 출력 대상 컬렉션은 샤딩될 수 없습니다. 그러나 입력 컬렉션은 샤딩될 수 있습니다.
  • 다음 SQL 문에 해당합니다.

    • MERGE.

    • INSERT INTO T2 SELECT FROM T1.

    • SELECT INTO T2 FROM T1.

    • 머티리얼라이즈드 뷰 생성/새로 고침.

  • 다음 SQL 문에 해당합니다.

    • INSERT INTO T2 SELECT FROM T1.

    • SELECT INTO T2 FROM T1.

경고

$merge 집계 중인 동일한 컬렉션 에 출력이 발생하면 문서가 여러 번 업데이트되거나 작업이 무한 루프가 발생할 수 있습니다. 이 동작은 $merge 에서 수행한 업데이트로 인해 디스크에 저장된 문서의 물리적 위치 변경될 때 발생합니다. 문서 의 물리적 위치 변경되면 $merge 에서 문서를 완전히 새로운 문서 로 간주하여 추가 업데이트를 수행할 수 있습니다. 이 동작에 대한 자세한 내용은 '할로윈 문제'를 참조하세요.

$merge는 집계 중인 컬렉션과 동일한 컬렉션으로 출력할 수 있습니다. $lookup과 같이 파이프라인의 다른 단계에 나타나는 컬렉션으로 출력할 수도 있습니다.

제한 사항
설명

집계 파이프라인은 트랜잭션 내에서 $merge를 사용할 수 없습니다.

집계 파이프라인은 $merge를 사용하여 time series 컬렉션으로 출력할 수 없습니다.

보기 정의
구체화된 뷰에서 분리

뷰 정의에는 $merge 단계를 포함할 수 없습니다. 뷰 정의에 중첩된 파이프라인이 포함된 경우(예: 뷰 정의에 $facet 단계가 포함된 경우) 이 $merge 단계 제한은 중첩된 파이프라인에도 적용됩니다.

$lookup 단계

$lookup 단계의 중첩 파이프라인$merge 단계를 포함할 수 없습니다.

$facet 단계

$facet 단계의 중첩 파이프라인$merge 단계를 포함할 수 없습니다.

$unionWith 단계

$unionWith 단계의 중첩 파이프라인$merge 단계를 포함할 수 없습니다.

"linearizable" readConcern

$merge 단계는 읽기 고려 "linearizable"과 함께 사용할 수 없습니다. db.collection.aggregate()에 대한 "linearizable" 읽기 고려 문제를 지정하면, $merge 단계를 파이프라인에 포함할 수 없습니다.

출력 컬렉션이 존재하지 않으면 $merge가 컬렉션을 생성합니다.

예를 들어, zoo 데이터베이스의 salaries 이라는 컬렉션은 직원 급여 및 부서 내역으로 채워집니다.

db.getSiblingDB("zoo").salaries.insertMany([
{ "_id" : 1, employee: "Ant", dept: "A", salary: 100000, fiscal_year: 2017 },
{ "_id" : 2, employee: "Bee", dept: "A", salary: 120000, fiscal_year: 2017 },
{ "_id" : 3, employee: "Cat", dept: "Z", salary: 115000, fiscal_year: 2017 },
{ "_id" : 4, employee: "Ant", dept: "A", salary: 115000, fiscal_year: 2018 },
{ "_id" : 5, employee: "Bee", dept: "Z", salary: 145000, fiscal_year: 2018 },
{ "_id" : 6, employee: "Cat", dept: "Z", salary: 135000, fiscal_year: 2018 },
{ "_id" : 7, employee: "Gecko", dept: "A", salary: 100000, fiscal_year: 2018 },
{ "_id" : 8, employee: "Ant", dept: "A", salary: 125000, fiscal_year: 2019 },
{ "_id" : 9, employee: "Bee", dept: "Z", salary: 160000, fiscal_year: 2019 },
{ "_id" : 10, employee: "Cat", dept: "Z", salary: 150000, fiscal_year: 2019 }
])

$group$merge 단계를 사용하여 현재 salaries 컬렉션에 있는 데이터에서 budgets(reporting 데이터베이스에 있는)라는 컬렉션을 처음 만들 수 있습니다.

참고

복제 세트 또는 독립형 배포의 경우 출력 데이터베이스가 존재하지 않으면 $merge가 데이터베이스를 생성하기도 합니다.

샤딩된 클러스터 배포의 경우, 지정된 출력 데이터베이스가 이미 존재해야 합니다.

db.getSiblingDB("zoo").salaries.aggregate( [
{ $group: { _id: { fiscal_year: "$fiscal_year", dept: "$dept" }, salaries: { $sum: "$salary" } } },
{ $merge : { into: { db: "reporting", coll: "budgets" }, on: "_id", whenMatched: "replace", whenNotMatched: "insert" } }
] )
  • 급여를 fiscal_yeardept 기준으로 그룹화하는 $group 단계.

  • $merge 단계는 앞의 $group 단계의 출력을 reporting 데이터베이스의 budgets 컬렉션에 기록합니다.

budgets 컬렉션의 문서를 보려면 다음과 같이 하세요:

db.getSiblingDB("reporting").budgets.find().sort( { _id: 1 } )

budgets 컬렉션에는 다음 문서가 포함되어 있습니다.

{ "_id" : { "fiscal_year" : 2017, "dept" : "A" }, "salaries" : 220000 }
{ "_id" : { "fiscal_year" : 2017, "dept" : "Z" }, "salaries" : 115000 }
{ "_id" : { "fiscal_year" : 2018, "dept" : "A" }, "salaries" : 215000 }
{ "_id" : { "fiscal_year" : 2018, "dept" : "Z" }, "salaries" : 280000 }
{ "_id" : { "fiscal_year" : 2019, "dept" : "A" }, "salaries" : 125000 }
{ "_id" : { "fiscal_year" : 2019, "dept" : "Z" }, "salaries" : 310000 }

다음 예시에서는 이전 예시의 컬렉션을 사용합니다.

예시 salaries 컬렉션에는 직원 급여 및 부서 기록이 포함되어 있습니다.

db.salaries.insertMany( [
{ _id : 1, employee: "Ant", dept: "A", salary: 100000, fiscal_year: 2017 },
{ _id : 2, employee: "Bee", dept: "A", salary: 120000, fiscal_year: 2017 },
{ _id : 3, employee: "Cat", dept: "Z", salary: 115000, fiscal_year: 2017 },
{ _id : 4, employee: "Ant", dept: "A", salary: 115000, fiscal_year: 2018 },
{ _id : 5, employee: "Bee", dept: "Z", salary: 145000, fiscal_year: 2018 },
{ _id : 6, employee: "Cat", dept: "Z", salary: 135000, fiscal_year: 2018 },
{ _id : 7, employee: "Gecko", dept: "A", salary: 100000, fiscal_year: 2018 },
{ _id : 8, employee: "Ant", dept: "A", salary: 125000, fiscal_year: 2019 },
{ _id : 9, employee: "Bee", dept: "Z", salary: 160000, fiscal_year: 2019 },
{ _id : 10, employee: "Cat", dept: "Z", salary: 150000, fiscal_year: 2019 }
] )

예시 budgets 컬렉션에는 연간 누적 예산이 포함되어 있습니다.

db.budgets.insertMany( [
{ _id : { "fiscal_year" : 2017, "dept" : "A" }, "salaries" : 220000 },
{ _id : { "fiscal_year" : 2017, "dept" : "Z" }, "salaries" : 115000 },
{ _id : { "fiscal_year" : 2018, "dept" : "A" }, "salaries" : 215000 },
{ _id : { "fiscal_year" : 2018, "dept" : "Z" }, "salaries" : 280000 },
{ _id : { "fiscal_year" : 2019, "dept" : "A" }, "salaries" : 125000 },
{ _id : { "fiscal_year" : 2019, "dept" : "Z" }, "salaries" : 310000 }
] )

현재 회계연도(이 예에서는 2019 ) 동안 새 직원이 salaries 컬렉션에 추가되고 새 인원수가 다음 연도에 미리 할당됩니다.

db.getSiblingDB("zoo").salaries.insertMany( [
{ _id : 11, employee: "Wren", dept: "Z", salary: 100000, fiscal_year: 2019 },
{ _id : 12, employee: "Zebra", dept: "A", salary: 150000, fiscal_year: 2019 },
{ _id : 13, employee: "headcount1", dept: "Z", salary: 120000, fiscal_year: 2020 },
{ _id : 14, employee: "headcount2", dept: "Z", salary: 120000, fiscal_year: 2020 }
] )

새 급여 정보를 반영하도록 budgets 컬렉션을 업데이트하기 위해 다음 집계 파이프라인은 다음을 사용합니다.

  • $match {3} 20192} 단계로 이 보다 크거나 같은 모든 문서를 찾습니다.

  • 급여를 fiscal_yeardept 기준으로 그룹화하는 $group 단계.

  • $merge를 사용하여 결과 집합을 budgets 컬렉션에 쓰고, 동일한 _id 값(이 예에서는 회계 연도와 부서가 있는 문서)을 가진 문서로 대체합니다. 컬렉션에 일치하는 문서가 없는 문서의 경우 $merge가 새 문서를 삽입합니다.

db.getSiblingDB("zoo").salaries.aggregate( [
{ $match : { fiscal_year: { $gte : 2019 } } },
{ $group: { _id: { fiscal_year: "$fiscal_year", dept: "$dept" }, salaries: { $sum: "$salary" } } },
{ $merge : { into: { db: "reporting", coll: "budgets" }, on: "_id", whenMatched: "replace", whenNotMatched: "insert" } }
] )

집계가 실행된 후 budgets 컬렉션에서 문서를 봅니다.

db.getSiblingDB("reporting").budgets.find().sort( { _id: 1 } )

budgets 컬렉션은 2019 회계연도의 새 급여 데이터를 통합하고 2020 회계연도에 대한 새 문서를 추가합니다.

{ _id : { "fiscal_year" : 2017, "dept" : "A" }, "salaries" : 220000 }
{ _id : { "fiscal_year" : 2017, "dept" : "Z" }, "salaries" : 115000 }
{ _id : { "fiscal_year" : 2018, "dept" : "A" }, "salaries" : 215000 }
{ _id : { "fiscal_year" : 2018, "dept" : "Z" }, "salaries" : 280000 }
{ _id : { "fiscal_year" : 2019, "dept" : "A" }, "salaries" : 275000 }
{ _id : { "fiscal_year" : 2019, "dept" : "Z" }, "salaries" : 410000 }
{ _id : { "fiscal_year" : 2020, "dept" : "Z" }, "salaries" : 240000 }

$merge가 컬렉션의 기존 데이터를 덮어쓰지 않도록 하려면 whenMatchedkeepExisting 또는 fail로 설정합니다.

zoo 데이터베이스의 예시 salaries 컬렉션에는 직원 급여 및 부서 내역이 포함되어 있습니다.

db.salaries.insertMany( [
{ _id : 1, employee: "Ant", dept: "A", salary: 100000, fiscal_year: 2017 },
{ _id : 2, employee: "Bee", dept: "A", salary: 120000, fiscal_year: 2017 },
{ _id : 3, employee: "Cat", dept: "Z", salary: 115000, fiscal_year: 2017 },
{ _id : 4, employee: "Ant", dept: "A", salary: 115000, fiscal_year: 2018 },
{ _id : 5, employee: "Bee", dept: "Z", salary: 145000, fiscal_year: 2018 },
{ _id : 6, employee: "Cat", dept: "Z", salary: 135000, fiscal_year: 2018 },
{ _id : 7, employee: "Gecko", dept: "A", salary: 100000, fiscal_year: 2018 },
{ _id : 8, employee: "Ant", dept: "A", salary: 125000, fiscal_year: 2019 },
{ _id : 9, employee: "Bee", dept: "Z", salary: 160000, fiscal_year: 2019 },
{ _id : 10, employee: "Cat", dept: "Z", salary: 150000, fiscal_year: 2019 }
] )

reporting 데이터베이스의 컬렉션 orgArchive 에는 지난 회계연도의 과거 부서별 조직 기록이 포함되어 있습니다. 보관된 기록은 수정해서는 안 됩니다.

db.orgArchive.insertMany( [
{ _id : ObjectId("5cd8c68261baa09e9f3622be"), "employees" : [ "Ant", "Gecko" ], "dept" : "A", "fiscal_year" : 2018 },
{ _id : ObjectId("5cd8c68261baa09e9f3622bf"), "employees" : [ "Ant", "Bee" ], "dept" : "A", "fiscal_year" : 2017 },
{ _id : ObjectId("5cd8c68261baa09e9f3622c0"), "employees" : [ "Bee", "Cat" ], "dept" : "Z", "fiscal_year" : 2018 },
{ _id : ObjectId("5cd8c68261baa09e9f3622c1"), "employees" : [ "Cat" ], "dept" : "Z", "fiscal_year" : 2017 }
] )

orgArchive 0} 컬렉션은 및 필드에 고유한 복합 인덱스가 fiscal_year dept 있습니다. 특히 동일한 회계 연도 및 부서 조합에 대해 최대 하나의 레코드가 있어야 합니다.

db.getSiblingDB("reporting").orgArchive.createIndex ( { fiscal_year: 1, dept: 1 }, { unique: true } )

현재 회계연도 말(이 예에서는 2019 )에 salaries 컬렉션에 다음 문서가 포함됩니다.

db.salaries.insertMany( [
{ _id : 1, "employee" : "Ant", "dept" : "A", "salary" : 100000, "fiscal_year" : 2017 },
{ _id : 2, "employee" : "Bee", "dept" : "A", "salary" : 120000, "fiscal_year" : 2017 },
{ _id : 3, "employee" : "Cat", "dept" : "Z", "salary" : 115000, "fiscal_year" : 2017 },
{ _id : 4, "employee" : "Ant", "dept" : "A", "salary" : 115000, "fiscal_year" : 2018 },
{ _id : 5, "employee" : "Bee", "dept" : "Z", "salary" : 145000, "fiscal_year" : 2018 },
{ _id : 6, "employee" : "Cat", "dept" : "Z", "salary" : 135000, "fiscal_year" : 2018 },
{ _id : 7, "employee" : "Gecko", "dept" : "A", "salary" : 100000, "fiscal_year" : 2018 },
{ _id : 8, "employee" : "Ant", "dept" : "A", "salary" : 125000, "fiscal_year" : 2019 },
{ _id : 9, "employee" : "Bee", "dept" : "Z", "salary" : 160000, "fiscal_year" : 2019 },
{ _id : 10, "employee" : "Cat", "dept" : "Z", "salary" : 150000, "fiscal_year" : 2019 },
{ _id : 11, "employee" : "Wren", "dept" : "Z", "salary" : 100000, "fiscal_year" : 2019 },
{ _id : 12, "employee" : "Zebra", "dept" : "A", "salary" : 150000, "fiscal_year" : 2019 },
{ _id : 13, "employee" : "headcount1", "dept" : "Z", "salary" : 120000, "fiscal_year" : 2020 },
{ _id : 14, "employee" : "headcount2", "dept" : "Z", "salary" : 120000, "fiscal_year" : 2020 }
] )

방금 종료된 회계연도 2019 를 포함하도록 orgArchive 컬렉션을 업데이트하기 위해 다음 집계 파이프라인은 다음을 사용합니다.

  • $match 단계는 fiscal_year2019 인 모든 문서를 찾는 단계입니다.

  • $group 단계는 fiscal_yeardept 별로 직원을 그룹화합니다.

  • $project 단계에서 _id 필드를 생략하고 별도의 deptfiscal_year 필드를 추가합니다. 문서가 $merge로 전달되면 $merge는 문서에 대한 새 _id 필드를 자동으로 생성합니다.

  • $merge 결과를 orgArchive 로 설정합니다.

    $merge 단계는 deptfiscal_year 필드에 있는 문서를 일치시키고 일치하지 않으면 fails로 표시합니다. 즉, 동일한 부서 및 회계 연도에 대한 문서가 이미 존재하는 경우 $merge 오류가 발생합니다.

db.getSiblingDB("zoo").salaries.aggregate( [
{ $match: { fiscal_year: 2019 }},
{ $group: { _id: { fiscal_year: "$fiscal_year", dept: "$dept" }, employees: { $push: "$employee" } } },
{ $project: { _id: 0, dept: "$_id.dept", fiscal_year: "$_id.fiscal_year", employees: 1 } },
{ $merge : { into : { db: "reporting", coll: "orgArchive" }, on: [ "dept", "fiscal_year" ], whenMatched: "fail" } }
] )

작업 후 orgArchive 컬렉션에는 다음 문서가 포함됩니다.

{ "_id" : ObjectId("5caccc6a66b22dd8a8cc419f"), "employees" : [ "Ahn", "Bess" ], "dept" : "A", "fiscal_year" : 2017 }
{ "_id" : ObjectId("5caccc6a66b22dd8a8cc419e"), "employees" : [ "Ahn", "Gee" ], "dept" : "A", "fiscal_year" : 2018 }
{ "_id" : ObjectId("5caccd0b66b22dd8a8cc438e"), "employees" : [ "Ahn", "Zeb" ], "dept" : "A", "fiscal_year" : 2019 }
{ "_id" : ObjectId("5caccc6a66b22dd8a8cc41a0"), "employees" : [ "Carl" ], "dept" : "Z", "fiscal_year" : 2017 }
{ "_id" : ObjectId("5caccc6a66b22dd8a8cc41a1"), "employees" : [ "Bess", "Carl" ], "dept" : "Z", "fiscal_year" : 2018 }
{ "_id" : ObjectId("5caccd0b66b22dd8a8cc438d"), "employees" : [ "Bess", "Carl", "Wen" ], "dept" : "Z", "fiscal_year" : 2019 }

orgArchive 컬렉션에 "A" 및/또는 "B" 부서에 대한 2019년 문서가 이미 포함되어 있는 경우 중복 키 오류로 인해 집계가 실패합니다. 그러나 오류가 발생하기 전에 삽입된 문서는 롤백되지 않습니다.

일치하는 문서에 대해 keepExisting을 지정하면 집계가 일치하는 문서에 영향을 주지 않고 중복 키 오류를 발생시키지 않습니다. 마찬가지로 바꾸기를 지정해도 작업이 실패하지는 않지만 기존 문서를 대체하게 됩니다.

기본적으로 집계 결과의 문서가 컬렉션의 문서와 일치하면 $merge 단계에서 문서가 병합됩니다.

예시 컬렉션 purchaseorders 은 분기 및 리전별 구매 주문 정보로 채워집니다.

db.purchaseorders.insertMany( [
{ _id: 1, quarter: "2019Q1", region: "A", qty: 200, reportDate: new Date("2019-04-01") },
{ _id: 2, quarter: "2019Q1", region: "B", qty: 300, reportDate: new Date("2019-04-01") },
{ _id: 3, quarter: "2019Q1", region: "C", qty: 700, reportDate: new Date("2019-04-01") },
{ _id: 4, quarter: "2019Q2", region: "B", qty: 300, reportDate: new Date("2019-07-01") },
{ _id: 5, quarter: "2019Q2", region: "C", qty: 1000, reportDate: new Date("2019-07-01") },
{ _id: 6, quarter: "2019Q2", region: "A", qty: 400, reportDate: new Date("2019-07-01") },
] )

예시 collection reportedsales 는 분기 및 리전별로 보고된 판매 정보로 채워집니다.

db.reportedsales.insertMany( [
{ _id: 1, quarter: "2019Q1", region: "A", qty: 400, reportDate: new Date("2019-04-02") },
{ _id: 2, quarter: "2019Q1", region: "B", qty: 550, reportDate: new Date("2019-04-02") },
{ _id: 3, quarter: "2019Q1", region: "C", qty: 1000, reportDate: new Date("2019-04-05") },
{ _id: 4, quarter: "2019Q2", region: "B", qty: 500, reportDate: new Date("2019-07-02") },
] )

보고 목적으로 다음 형식으로 분기별로 데이터를 보려고 한다고 가정합니다.

{ "_id" : "2019Q1", "sales" : 1950, "purchased" : 1200 }
{ "_id" : "2019Q2", "sales" : 500, "purchased" : 1700 }

$merge를 사용하여 purchaseorders 컬렉션과 reportedsales 컬렉션의 결과를 병합하여 새 컬렉션 quarterlyreport를 만들 수 있습니다.

0} 컬렉션을 만들려면 다음 파이프라인을 사용할 수 있습니다:quarterlyreport

db.purchaseorders.aggregate( [
{ $group: { _id: "$quarter", purchased: { $sum: "$qty" } } }, // group purchase orders by quarter
{ $merge : { into: "quarterlyreport", on: "_id", whenMatched: "merge", whenNotMatched: "insert" } }
])
첫 번째 단계:

2} 단계는 $group 분기별로 그룹화하고 를 사용하여 필드를 $sumqty purchased 필드에 추가합니다. 예시:

quarterlyreport 0} 컬렉션을 만들려면 이 파이프라인을 사용할 수 있습니다:

{ "_id" : "2019Q2", "purchased" : 1700 }
{ "_id" : "2019Q1", "purchased" : 1200 }
두 번째 단계:
$merge 단계에서는 동일한 데이터베이스의 quarterlyreport 컬렉션에 문서를 씁니다. 해당 단계가 컬렉션에서 _id 필드와 일치하는 기존 문서를 찾으면 해당 단계는 일치하는 문서를 병합합니다. 그렇지 않으면 단계가 문서를 삽입합니다. 처음 생성할 때는 일치하는 문서가 없어야 합니다.

컬렉션의 문서를 보려면 다음 작업을 실행합니다.

db.quarterlyreport.find().sort( { _id: 1 } )

컬렉션에는 다음 문서가 포함되어 있습니다.

{ "_id" : "2019Q1", "sales" : 1200, "purchased" : 1200 }
{ "_id" : "2019Q2", "sales" : 1700, "purchased" : 1700 }

마찬가지로, reportedsales 컬렉션에 대해 다음 집계 파이프라인을 실행하여 판매 결과를 quarterlyreport 컬렉션에 병합합니다.

db.reportedsales.aggregate( [
{ $group: { _id: "$quarter", sales: { $sum: "$qty" } } }, // group sales by quarter
{ $merge : { into: "quarterlyreport", on: "_id", whenMatched: "merge", whenNotMatched: "insert" } }
])
첫 번째 단계:

2} 단계는 $group 분기별로 그룹화하고 를 사용하여 필드를 $sumqty sales 필드에 추가합니다. 예시:

{ "_id" : "2019Q2", "sales" : 500 }
{ "_id" : "2019Q1", "sales" : 1950 }
두 번째 단계:
$merge 스테이지에서는 동일한 데이터베이스의 quarterlyreport 컬렉션에 문서를 씁니다. _id 필드(분기)에서 일치하는 기존 문서가 컬렉션에서 발견되면 스테이지에서 일치하는 문서를 병합합니다. 그렇지 않으면 스테이지가 문서를 삽입합니다.

데이터가 병합된 후 quarterlyreport 컬렉션의 문서를 보려면 다음 작업을 실행하세요.

db.quarterlyreport.find().sort( { _id: 1 } )

컬렉션에는 다음 문서가 포함되어 있습니다.

{ "_id" : "2019Q1", "sales" : 1950, "purchased" : 1200 }
{ "_id" : "2019Q2", "sales" : 500, "purchased" : 1700 }

$merge는 문서가 일치할 때 사용자 지정 업데이트 파이프라인을 사용할 수 있습니다. whenMatched 파이프라인은 다음과 같은 단계를 가질 수 있습니다.

예시 컬렉션 votes 은 일일 투표 집계로 채워집니다. 다음 문서로 collection을 생성합니다.

db.votes.insertMany( [
{ date: new Date("2019-05-01"), "thumbsup" : 1, "thumbsdown" : 1 },
{ date: new Date("2019-05-02"), "thumbsup" : 3, "thumbsdown" : 1 },
{ date: new Date("2019-05-03"), "thumbsup" : 1, "thumbsdown" : 1 },
{ date: new Date("2019-05-04"), "thumbsup" : 2, "thumbsdown" : 2 },
{ date: new Date("2019-05-05"), "thumbsup" : 6, "thumbsdown" : 10 },
{ date: new Date("2019-05-06"), "thumbsup" : 13, "thumbsdown" : 16 }
] )

또 다른 예시 컬렉션 monthlytotals 에는 최신 월별 투표 합계가 있습니다. 다음 문서로 collection을 생성합니다.

db.monthlytotals.insertOne(
{ "_id" : "2019-05", "thumbsup" : 26, "thumbsdown" : 31 }
)

매일 하루가 끝나면 그날의 투표가 votes 컬렉션에 삽입됩니다:

db.votes.insertOne(
{ date: new Date("2019-05-07"), "thumbsup" : 14, "thumbsdown" : 10 }
)

사용자 지정 파이프라인과 함께 $merge를 사용하여 컬렉션 monthlytotals의 기존 문서를 업데이트할 수 있습니다:

db.votes.aggregate([
{ $match: { date: { $gte: new Date("2019-05-07"), $lt: new Date("2019-05-08") } } },
{ $project: { _id: { $dateToString: { format: "%Y-%m", date: "$date" } }, thumbsup: 1, thumbsdown: 1 } },
{ $merge: {
into: "monthlytotals",
on: "_id",
whenMatched: [
{ $addFields: {
thumbsup: { $add:[ "$thumbsup", "$$new.thumbsup" ] },
thumbsdown: { $add: [ "$thumbsdown", "$$new.thumbsdown" ] }
} } ],
whenNotMatched: "insert"
} }
])
첫 번째 단계:

$match 단계에서는 특정 날짜의 투표를 찾습니다. 예시:

{ "_id" : ObjectId("5ce6097c436eb7e1203064a6"), "date" : ISODate("2019-05-07T00:00:00Z"), "thumbsup" : 14, "thumbsdown" : 10 }
두 번째 단계:

$project 단계는 _id 필드를 연도-월 문자열로 설정합니다. 예시:

{ "thumbsup" : 14, "thumbsdown" : 10, "_id" : "2019-05" }
세 번째 단계:

$merge 단계에서는 동일한 데이터베이스의 monthlytotals 컬렉션에 문서를 씁니다. 스테이지가 컬렉션에서 _id 필드와 일치하는 기존 문서를 찾으면 스테이지는 파이프라인을 사용하여 thumbsup 표와 thumbsdown 표를 추가합니다.

  • 이 파이프라인은 결과 문서의 필드에 직접 액세스할 수 없습니다. 결과 문서의 thumbsup 필드와 thumbsdown 필드에 액세스하기 위해 파이프라인은 $$new 변수 (예: $$new.thumbsup$new.thumbsdown) 를 사용합니다.

  • 이 파이프라인은 컬렉션에 있는 기존 문서의 thumbsup 필드와 thumbsdown 필드 (예: $thumbsup$thumbsdown) 에 직접 액세스할 수 있습니다.

결과 문서가 기존 문서를 대체합니다.

병합 작업 후 monthlytotals 컬렉션의 문서를 보려면 다음 작업을 실행하세요.

db.monthlytotals.find()

컬렉션에는 다음 문서가 포함되어 있습니다.

{ "_id" : "2019-05", "thumbsup" : 40, "thumbsdown" : 41 }

$merge 단계의 whenMatched 필드에 변수를 사용할 수 있습니다. 변수를 사용하려면 먼저 변수를 정의해야 합니다.

다음 중 하나 또는 둘 모두에서 변수를 정의합니다:

때매치에서변수를 사용하려면:

변수 이름과 함께 이중 달러 기호 ($$) 접두사를 $$<variable_name> 형식으로 지정합니다. 예시: $$year. 변수가 문서로 설정된 경우 $$<variable_name>.<field> 형식으로 문서 필드를 포함할 수도 있습니다. 예시: $$year.month.

아래 탭은 병합 단계, 집계 명령 또는 둘 다에서 변수가 정의될 때의 동작을 보여줍니다.

$merge 단계에서 변수를 정의 하고 whenMatched 필드에서 변수를 사용할 수 있습니다.

예시:

db.cakeSales.insertOne( [
{ _id: 1, flavor: "chocolate", salesTotal: 1580,
salesTrend: "up" }
] )
db.runCommand( {
aggregate: db.cakeSales.getName(),
pipeline: [ {
$merge: {
into: db.cakeSales.getName(),
let : { year: "2020" },
whenMatched: [ {
$addFields: { "salesYear": "$$year" }
} ]
}
} ],
cursor: {}
} )
db.cakeSales.find()

예시입니다:

  • 라는 이름의 컬렉션 생성 cakeSales

  • $merge let에서 year 변수를 정의하는 aggregate 명령을 실행하고 whenMatched를 사용하여 cakeSales에 연도를 추가합니다.

  • retrieves the cakeSales document

출력:

{ "_id" : 1, "flavor" : "chocolate", "salesTotal" : 1580,
"salesTrend" : "up", "salesYear" : "2020" }

버전 5.0에 추가 되었습니다.:

aggregate 명령 let에서 변수를 정의하고 $merge 단계 whenMatched 필드에서 변수를 사용할 수 있습니다.

예시:

db.cakeSales.insertOne(
{ _id: 1, flavor: "chocolate", salesTotal: 1580,
salesTrend: "up" }
)
db.runCommand( {
aggregate: db.cakeSales.getName(),
pipeline: [ {
$merge: {
into: db.cakeSales.getName(),
whenMatched: [ {
$addFields: { "salesYear": "$$year" } }
] }
}
],
cursor: {},
let : { year: "2020" }
} )
db.cakeSales.find()

예시입니다:

  • 라는 이름의 컬렉션 생성 cakeSales

  • aggregate 명령 let에서 year 변수를 정의하는 aggregate 명령을 실행하고 whenMatched를 사용하여 cakeSales에 연도를 추가합니다.

  • retrieves the cakeSales document

출력:

{ "_id" : 1, "flavor" : "chocolate", "salesTotal" : 1580,
"salesTrend" : "up", "salesYear" : "2020" }

$merge 단계에서 변수를 정의할 수 있으며 MongoDB 5.0부터는 aggregate 명령입니다.

동일한 이름을 가진 두 개의 변수가 $merge 단계와 aggregate 명령에 정의된 경우 $merge 단계 변수가 사용됩니다.

이 예에서는 year: "2019" 명령 aggregate 변수 대신 year: "2020" $merge 단계 변수가 사용됩니다.

db.cakeSales.insertOne(
{ _id: 1, flavor: "chocolate", salesTotal: 1580,
salesTrend: "up" }
)
db.runCommand( {
aggregate: db.cakeSales.getName(),
pipeline: [ {
$merge: {
into: db.cakeSales.getName(),
let : { year: "2020" },
whenMatched: [ {
$addFields: { "salesYear": "$$year" }
} ]
}
} ],
cursor: {},
let : { year: "2019" }
} )
db.cakeSales.find()

출력:

{
_id: 1,
flavor: 'chocolate',
salesTotal: 1580,
salesTrend: 'up',
salesYear: '2020'
}

다음 Movie 클래스는 이 예시에 사용된 문서를 모델링합니다.

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

MongoDB .NET/ C# 운전자 사용하여 $merge 집계 파이프라인 에 단계를 추가하려면 PipelineDefinition 객체 에서 UnionWith() 메서드를 호출합니다.

Merge() 메서드를 호출할 때는 MergeStageOptions 클래스의 인스턴스 전달해야 합니다. 이 객체 사용하면 일치하는 문서를 처리하다 방법과 같은 $merge 단계에 대한 옵션을 지정할 수 있습니다.

다음 예시 파이프 파이프라인 의 문서를 movies 컬렉션 에 병합하는 파이프라인 단계를 만듭니다. MergeStageOptions 객체 다음 옵션을 지정합니다.

  • OnFieldNames 옵션은 작업이 "_id" 필드를 사용하여 일치하는 문서를 식별하도록 지정합니다.

  • WhenMatched 옵션은 소스 컬렉션의 문서가 대상 컬렉션의 문서와 일치하는 경우 일치하는 문서를 대체하도록 지정합니다.

  • WhenNotMatched 옵션은 소스 컬렉션의 문서가 대상 컬렉션의 문서와 일치하지 않는 경우 작업이 문서를 대상 컬렉션에 삽입하도록 지정합니다.

var pipeline = new EmptyPipelineDefinition<Movie>()
.Merge(_targetCollection,
new MergeStageOptions<Movie>()
{
OnFieldNames = new List<string>() { "_id" },
WhenMatched = MergeStageWhenMatched.Replace,
WhenNotMatched = MergeStageWhenNotMatched.Insert,
});
{ "_id": "...", "title": "Back to the Future", "metacritic": 96 }
{ "_id": "...", "title": "Jurassic Park", "metacritic": 68 }
{ "_id": "...", "title": "The Shawshank Redemption", "metacritic": 80 }

이 페이지의 Node.js 예제에서는 Atlas 샘플 데이터 세트sample_mflix 데이터베이스 사용합니다. 무료 MongoDB Atlas cluster 생성하고 샘플 데이터 세트를 로드하는 방법을 학습하려면 MongoDB Node.js 운전자 설명서에서 시작하기 를 참조하세요.

MongoDB Node.js 운전자 사용하여 집계 파이프라인 에 $merge 단계를 추가하려면 파이프라인 객체 에서 $merge 연산자 사용합니다.

다음 예시 파이프 파이프라인 의 문서를 movies 컬렉션 에 병합하는 파이프라인 단계를 만듭니다. 이 예시 에는 다음 필드가 포함되어 있습니다.

  • on 옵션은 작업이 "_id""title" 필드를 사용하여 소스 컬렉션 과 movies 컬렉션 에서 일치하는 문서를 찾도록 지정합니다.

  • whenMatched 옵션은 소스 컬렉션 의 문서 movies 컬렉션 의 문서 와 일치하는 경우 movies 컬렉션 의 문서 대체하도록 지정합니다.

  • whenNotMatched 옵션은 소스 컬렉션 의 문서 movies 컬렉션 의 문서 와 일치하지 않는 경우 작업이 movies 컬렉션 에 문서 삽입하도록 지정합니다.

그런 다음 이 예시 에서는 집계 파이프라인 실행합니다.

const pipeline = [
{
$merge: {
into: "movies",
on: ["_id", "title"],
whenMatched: "replace",
whenNotMatched: "insert"
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;