정의
$lookup
버전 8.0에서 변경되었습니다.
동일한 데이터베이스 내 컬렉션에 대해 왼쪽 외부 조인을 수행하여, 처리를 위해 외부 컬렉션의 문서를 필터링합니다.
$lookup
단계에서는 각 입력 문서에 새 배열 필드를 추가합니다. 새 배열 필드에는 외부 컬렉션에서 일치하는 문서가 포함됩니다.$lookup
단계에서는 이렇게 재구성된 문서를 다음 단계로 넘깁니다.MongoDB 5.1부터 샤딩된 컬렉션에
$lookup
을 사용할 수 있습니다.서로 다른 두 컬렉션의 요소를 결합하려면
$unionWith
파이프라인 단계를 사용합니다.
호환성
다음 환경에서 호스팅되는 배포에 $lookup
사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
$lookup
단계 구문:
{ $lookup: { from: <collection to join>, localField: <field from the input documents>, foreignField: <field from the documents of the "from" collection>, let: { <var_1>: <expression>, …, <var_n>: <expression> }, pipeline: [ <pipeline to run> ], as: <output array field> } }
$lookup
은 다음과 같은 필드가 있는 문서를 수락합니다.
필드 | 필요성 | 설명 |
---|---|---|
필수 사항 | 동일한 데이터베이스에서 로컬 컬렉션에 조인할 외부 컬렉션을 지정합니다. 일부 경우에는 첫 번째 단계로 MongoDB 5.1부터 | |
| ||
| 로컬 문서의 외부 문서 | |
옵션 | 파이프라인 단계에서 사용할 변수를 지정합니다. 변수 표현식을 사용하여 파이프라인 단계에서 변수를 참조하려면 let 변수는 에 중첩된 추가 단계를
| |
| 외부 컬렉션에서 실행할 에는
파이프라인 단계에서 변수를 참조하려면 let 변수는 에 중첩된 추가 단계를
| |
필수 사항 | 입력 문서에 추가할 새 배열 필드의 이름을 지정합니다. 새 배열 필드에는 |
단일 조인 조건으로 동일성 일치
입력 문서의 필드와 외부 컬렉션의 문서 필드 간에 동등성 매치를 수행하기 위해, $lookup
단계는 다음과 같은 구문을 가집니다.
{ $lookup: { from: <collection to join>, localField: <field from the input documents>, foreignField: <field from the documents of the "from" collection>, pipeline: [ <pipeline to run> ], as: <output array field> } }
참고
이 예시 에서 pipeline
은 선택 사항이며 로컬 및 외부 동일성 단계 이후에 실행됩니다.
이 작업은 다음과 같은 유사 SQL 문장에 해당합니다.
SELECT *, ( SELECT ARRAY_AGG(*) FROM <collection to join> WHERE <foreignField> = <collection.localField> ) AS <output array field> FROM collection;
참고
이 페이지의 SQL 문은 MongoDB 집계 파이프라인 구문과 비교할 수 있도록 포함되어 있습니다. SQL 문을 실행할 수 없습니다.
MongoDB 예시는 이 페이지를 참조하세요.
외래 컬렉션에 대한 조인 조건 및 하위 쿼리
MongoDB는 다음을 지원합니다.
외부 컬렉션에서 파이프라인 실행하기.
여러 조인 조건.
상관관계가 있는 하위 쿼리와 상관관계가 없는 하위 쿼리.
MongoDB 에서 상관 관계가 없는 하위 쿼리는 모든 입력 문서 동일한 결과를 반환한다는 의미입니다. 상관 하위 쿼리는 로컬 $lookup
또는 input
컬렉션의 필드를 사용하여 각 수신 문서 와 관련된 결과를 반환하는 단계의 파이프라인 입니다.
참고
MongoDB 5.0부터는 $lookup
파이프라인 단계에서 $sample
단계, $sampleRate
연산자 또는 $rand
연산자를 포함하는 상관 관계가 없는 하위 쿼리의 경우, 반복 시 항상 하위 쿼리가 다시 실행됩니다. 이전에는 하위 쿼리 출력 크기에 따라 하위 쿼리 출력이 캐시되거나 하위 쿼리가 다시 실행되었습니다.
MongoDB 상관 서브쿼리는 내부 쿼리가 외부 쿼리 값을 참조하는 SQL 상관 서브쿼리와 유사합니다. SQL 비연관 서브쿼리는 외부 쿼리 값을 참조하지 않습니다.
MongoDB 5.0은 상관관계가 있는 간결한 하위 쿼리도 지원합니다.
두 컬렉션에 대해 상관 관계 및 비상관 관계 하위 쿼리를 수행하고 단일 동등성 매치 외에 다른 조인 조건을 수행하려면 이 $lookup
구문을 사용합니다.
{ $lookup: { from: <foreign collection>, let: { <var_1>: <expression>, …, <var_n>: <expression> }, pipeline: [ <pipeline to run on foreign collection> ], as: <output array field> } }
이 작업은 다음과 같은 유사 SQL 문장에 해당합니다.
SELECT *, <output array field> FROM collection WHERE <output array field> IN ( SELECT <documents as determined from the pipeline> FROM <collection to join> WHERE <pipeline> );
다음 예시를 참조하세요.
간결한 구문을 사용한 상호 연관된 하위 쿼리
버전 5.0에 추가.
MongoDB 5.0부터는 상관 하위 쿼리에 간결한 구문을 사용할 수 있습니다. 상관 하위 쿼리는 외부 컬렉션과 aggregate()
메서드가 실행된 '로컬' 컬렉션의 문서 필드를 참조합니다.
다음과 같은 새롭고 간결한 구문은 $expr
연산자 내부의 외부 및 로컬 필드에 대한 동등성 매치 요구 사항을 제거합니다.
{ $lookup: { from: <foreign collection>, localField: <field from local collection's documents>, foreignField: <field from foreign collection's documents>, let: { <var_1>: <expression>, …, <var_n>: <expression> }, pipeline: [ <pipeline to run> ], as: <output array field> } }
이 작업은 다음과 같은 유사 SQL 문장에 해당합니다.
SELECT *, <output array field> FROM localCollection WHERE <output array field> IN ( SELECT <documents as determined from the pipeline> FROM <foreignCollection> WHERE <foreignCollection.foreignField> = <localCollection.localField> AND <pipeline match condition> );
이 예시를 참조하세요.
행동
보기 및 데이터 정렬
$lookup
또는 $graphLookup
등 여러 뷰가 포함된 집계를 수행하는 경우 반드시 뷰의 데이터 정렬이 동일해야 합니다.
제한 사항
$out
또는 $merge
단계는 $lookup
단계에 포함할 수 없습니다. 즉, 외부 컬렉션에 대한 파이프라인을 지정할 때 pipeline
필드에 어느 단계도 포함할 수 없습니다.
{ $lookup: { from: <collection to join>, let: { <var_1>: <expression>, …, <var_n>: <expression> }, pipeline: [ <pipeline to execute on the foreign collection> ], // Cannot include $out or $merge as: <output array field> } }
Atlas Search 지원
MongoDB 6.0부터 $lookup
파이프라인에서 Atlas Search $search
또는 $searchMeta
단계를 지정하여 Atlas 클러스터에서 컬렉션을 검색할 수 있습니다. $search
또는 $searchMeta
단계는 $lookup
파이프라인 내의 첫 번째 단계여야 합니다.
예를 들어, 외부 컬렉션에서 조건 및 하위 쿼리를 조인하거나 간결한 구문을 사용하여 상관 하위 쿼리를 실행하는 경우 아래와 같이 파이프라인에 $search
또는 $searchMeta
를 지정할 수 있습니다.
$search
를 사용한 $lookup
의 예를 보려면 $lookup을 사용하여 Atlas Search $search 쿼리 실행하기라는 Atlas Search 튜토리얼을 참조하세요.
샤드 컬렉션
MongoDB 5.1부터 $lookup
단계의 from
파라미터에서 샤딩된 컬렉션을 지정할 수 있습니다.
MongoDB 8.0부터 샤딩된 컬렉션을 대상으로 하는 트랜잭션 내에서 $lookup
단계를 사용할 수 있습니다.
슬롯 기반 쿼리 실행 엔진
6.0버전부터 파이프라인의 모든 이전 단계가 슬롯 기반 실행 엔진에서도 실행될 수 있고 다음 조건 중 어느 것도 참이 아닌 경우 MongoDB는 슬롯 기반 실행 쿼리 엔진을 사용하여 $lookup
단계를 실행할 수 있습니다.
$lookup
작업은 외부 컬렉션에서 파이프라인을 실행합니다. 이러한 종류의 작업 예시를 보려면 외부 컬렉션의 조인 조건 및 하위 쿼리를 참조하세요.$lookup
의localField
또는foreignField
는 숫자 구성 요소를 지정합니다. 예시:{ localField: "restaurant.0.review" }
파이프라인에서
$lookup
의from
필드는 뷰 또는 샤드 컬렉션을 지정합니다.
자세한 내용은 $lookup
최적화를 참조하세요.
성능 고려 사항
$lookup
성능은 수행되는 작업 유형에 따라 달라집니다. 다양한 $lookup
작업에 대한 성능 고려 사항은 다음 표를 참조하세요.
$lookup 작업 | 성능 고려 사항 |
---|---|
| |
| |
|
일반적인 성능 전략은 인덱싱 전략 및 쿼리 최적화를 참조하세요.
중요
쿼리 내에서 $lookup
을 과도하게 사용하면 성능이 저하될 수 있습니다. 여러 $lookup
단계를 피하려면 쿼리 성능을 최적화하는 임베디드 데이터 모델을 고려하세요.
예시
단일 동일성 조인 수행하기 - $lookup
이 문서로 orders
컬렉션을 만듭니다.
db.orders.insertMany( [ { _id: 1, item: "almonds", price: 12, quantity: 2 }, { _id: 2, item: "pecans", price: 20, quantity: 1 }, { _id: 3 } ] )
이 문서로 다른 컬렉션 inventory
를 만듭니다.
db.inventory.insertMany( [ { _id: 1, sku: "almonds", description: "product 1", instock: 120 }, { _id: 2, sku: "bread", description: "product 2", instock: 80 }, { _id: 3, sku: "cashews", description: "product 3", instock: 60 }, { _id: 4, sku: "pecans", description: "product 4", instock: 70 }, { _id: 5, sku: null, description: "Incomplete" }, { _id: 6 } ] )
orders
컬렉션에 대한 다음 집계 작업은 orders
컬렉션의 item
필드와 inventory
컬렉션의 sku
필드를 사용하여 orders
문서를 inventory
컬렉션의 문서와 결합합니다.
db.orders.aggregate( [ { $lookup: { from: "inventory", localField: "item", foreignField: "sku", as: "inventory_docs" } } ] )
이 작업은 다음 문서를 반환합니다.
{ _id: 1, item: "almonds", price: 12, quantity: 2, inventory_docs: [ { _id: 1, sku: "almonds", description: "product 1", instock: 120 } ] } { _id: 2, item: "pecans", price: 20, quantity: 1, inventory_docs: [ { _id: 4, sku: "pecans", description: "product 4", instock: 70 } ] } { _id: 3, inventory_docs: [ { _id: 5, sku: null, description: "Incomplete" }, { _id: 6 } ] }
이 작업은 다음과 같은 유사 SQL 문장에 해당합니다.
SELECT *, inventory_docs FROM orders WHERE inventory_docs IN ( SELECT * FROM inventory WHERE sku = orders.item );
자세한 내용은 동등성 매치 성능 고려 사항을 참조하세요.
배열에 $lookup
사용
localField
가 배열인 경우 $unwind
단계 없이 스칼라 foreignField
에 일치시킬 수 있습니다.
예를 들어 다음 문서를 사용하여 예시 컬렉션 classes
를 만듭니다.
db.classes.insertMany( [ { _id: 1, title: "Reading is ...", enrollmentlist: [ "giraffe2", "pandabear", "artie" ], days: ["M", "W", "F"] }, { _id: 2, title: "But Writing ...", enrollmentlist: [ "giraffe1", "artie" ], days: ["T", "F"] } ] )
이 문서로 다른 컬렉션 members
를 만듭니다.
db.members.insertMany( [ { _id: 1, name: "artie", foreign: new Date("2016-05-01"), status: "A" }, { _id: 2, name: "giraffe", foreign: new Date("2017-05-01"), status: "D" }, { _id: 3, name: "giraffe1", foreign: new Date("2017-10-01"), status: "A" }, { _id: 4, name: "panda", foreign: new Date("2018-10-11"), status: "A" }, { _id: 5, name: "pandabear", foreign: new Date("2018-12-01"), status: "A" }, { _id: 6, name: "giraffe2", foreign: new Date("2018-12-01"), status: "D" } ] )
다음 집계 작업은 classes
컬렉션의 문서를 members
컬렉션과 결합하여 enrollmentlist
필드를 name
필드와 일치시킵니다.
db.classes.aggregate( [ { $lookup: { from: "members", localField: "enrollmentlist", foreignField: "name", as: "enrollee_info" } } ] )
이 연산은 다음을 반환합니다:
{ _id: 1, title: "Reading is ...", enrollmentlist: [ "giraffe2", "pandabear", "artie" ], days: [ "M", "W", "F" ], enrollee_info: [ { _id: 1, name: "artie", foreign: ISODate("2016-05-01T00:00:00Z"), status: "A" }, { _id: 5, name: "pandabear", foreign: ISODate("2018-12-01T00:00:00Z"), status: "A" }, { _id: 6, name: "giraffe2", foreign: ISODate("2018-12-01T00:00:00Z"), status: "D" } ] } { _id: 2, title: "But Writing ...", enrollmentlist: [ "giraffe1", "artie" ], days: [ "T", "F" ], enrollee_info: [ { _id: 1, name: "artie", foreign: ISODate("2016-05-01T00:00:00Z"), status: "A" }, { _id: 3, name: "giraffe1", foreign: ISODate("2017-10-01T00:00:00Z"), status: "A" } ] }
$mergeObjects
과 함께 $lookup
사용
$mergeObjects
연산자는 여러 문서를 단일 문서로 결합합니다.
이 문서로 orders
컬렉션을 만듭니다.
db.orders.insertMany( [ { _id: 1, item: "almonds", price: 12, quantity: 2 }, { _id: 2, item: "pecans", price: 20, quantity: 1 } ] )
이 문서로 다른 컬렉션 items
를 만듭니다.
db.items.insertMany( [ { _id: 1, item: "almonds", description: "almond clusters", instock: 120 }, { _id: 2, item: "bread", description: "raisin and nut bread", instock: 80 }, { _id: 3, item: "pecans", description: "candied pecans", instock: 60 } ] )
다음 작업은 먼저 $lookup
단계를 사용하여 item
필드를 기준으로 두 컬렉션을 조인한 다음 $replaceRoot
에서 $mergeObjects
를 사용하여 items
와 orders
에서 외부 문서를 병합합니다.
db.orders.aggregate( [ { $lookup: { from: "items", localField: "item", // field in the orders collection foreignField: "item", // field in the items collection as: "fromItems" } }, { $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$fromItems", 0 ] }, "$$ROOT" ] } } }, { $project: { fromItems: 0 } } ] )
이 작업은 다음 문서를 반환합니다.
{ _id: 1, item: 'almonds', description: 'almond clusters', instock: 120, price: 12, quantity: 2 }, { _id: 2, item: 'pecans', description: 'candied pecans', instock: 60, price: 20, quantity: 1 }
다중 조인 조건 및 상관관계 하위 쿼리 사용
파이프라인은 외부 컬렉션에서 실행할 수 있으며 여러 조인 조건을 포함할 수 있습니다. $expr
연산자를 사용하면 접속사 및 비동등성 매치를 포함한 더 복잡한 조인 조건이 가능합니다.
조인 조건은 aggregate()
메서드가 실행된 로컬 컬렉션의 필드를 참조하고 외부 컬렉션의 필드를 참조할 수 있습니다. 이렇게 하면 두 컬렉션 간에 상관 하위 쿼리가 가능합니다.
MongoDB 5.0은 상관관계가 있는 간결한 하위 쿼리를 지원합니다.
이 문서로 orders
컬렉션을 만듭니다.
db.orders.insertMany( [ { _id: 1, item: "almonds", price: 12, ordered: 2 }, { _id: 2, item: "pecans", price: 20, ordered: 1 }, { _id: 3, item: "cookies", price: 10, ordered: 60 } ] )
이 문서로 다른 컬렉션 warehouses
를 만듭니다.
db.warehouses.insertMany( [ { _id: 1, stock_item: "almonds", warehouse: "A", instock: 120 }, { _id: 2, stock_item: "pecans", warehouse: "A", instock: 80 }, { _id: 3, stock_item: "almonds", warehouse: "B", instock: 60 }, { _id: 4, stock_item: "cookies", warehouse: "B", instock: 40 }, { _id: 5, stock_item: "cookies", warehouse: "A", instock: 80 } ] )
다음 예제입니다.
orders.item
및warehouse.stock_item
필드에 대한 조인과 함께 상관된 하위 쿼리를 사용합니다.재고가 있는 품목의 수량이 주문한 수량을 충족할 수 있는지 확인합니다.
db.orders.aggregate( [ { $lookup: { from : "warehouses", localField : "item", foreignField : "stock_item", let : { order_qty: "$ordered" }, pipeline : [ { $match : { $expr : [ { $gte: [ "$instock", "$$order_qty" ] } ] } }, { $project : { stock_item: 0, _id: 0 } } ], as : "stockdata" } } ] )
이 작업은 다음 문서를 반환합니다.
{ _id: 1, item: 'almonds', price: 12, ordered: 2, stockdata: [ { warehouse: 'A', instock: 120 }, { warehouse: 'B', instock: 60 } ] }, { _id: 2, item: 'pecans', price: 20, ordered: 1, stockdata: [ { warehouse: 'A', instock: 80 } ] }, { _id: 3, item: 'cookies', price: 10, ordered: 60, stockdata: [ { warehouse: 'A', instock: 80 } ] }
이 작업은 다음과 같은 유사 SQL 문장에 해당합니다.
SELECT *, stockdata FROM orders WHERE stockdata IN ( SELECT warehouse, instock FROM warehouses WHERE stock_item = orders.item AND instock >= orders.ordered );
$expr
연산자에 배치된 $eq
, $lt
, $lte
, $gt
, $gte
비교 연산자는 $lookup
단계에서 참조된 from
컬렉션의 인덱스를 사용할 수 있습니다. 제한 사항:
인덱스는 필드와 상수 간의 비교에만 사용할 수 있으므로
let
피연산자는 상수로 해결되어야 합니다.예를 들어
$a
및 상수 값 간의 비교에는 인덱스를 사용할 수 있지만,$a
및$b
간의 비교에는 인덱스를 사용할 수 없습니다.let
피연산자가 비어 있거나 누락된 값으로 확인되는 비교에는 인덱스가 사용되지 않습니다.다중 키 인덱스 는 사용되지 않습니다.
예를 들어 warehouses
컬렉션에 인덱스 { stock_item: 1, instock: 1 }
가 존재하는 경우입니다.
warehouses.stock_item
필드의 동등성 매치는 인덱스를 사용합니다.warehouses.instock
필드에 대한 쿼리의 범위 부분도 복합 인덱스의 인덱스 필드를 사용합니다.
상관관계가 없는 하위 쿼리 수행하기 - $lookup
집계 파이프라인 $lookup
단계는 외부 컬렉션에서 파이프라인을 실행할 수 있으며, 이는 비상관 하위 쿼리를 허용합니다. 비상관 하위 쿼리는 로컬 문서 필드를 참조하지 않습니다.
참고
MongoDB 5.0부터는 $lookup
파이프라인 단계에서 $sample
단계, $sampleRate
연산자 또는 $rand
연산자를 포함하는 상관 관계가 없는 하위 쿼리의 경우, 반복 시 항상 하위 쿼리가 다시 실행됩니다. 이전에는 하위 쿼리 출력 크기에 따라 하위 쿼리 출력이 캐시되거나 하위 쿼리가 다시 실행되었습니다.
이 문서로 absences
컬렉션을 만듭니다.
db.absences.insertMany( [ { _id: 1, student: "Ann Aardvark", sickdays: [ new Date ("2018-05-01"),new Date ("2018-08-23") ] }, { _id: 2, student: "Zoe Zebra", sickdays: [ new Date ("2018-02-01"),new Date ("2018-05-23") ] }, ] )
이 문서로 다른 컬렉션 holidays
를 만듭니다.
db.holidays.insertMany( [ { _id: 1, year: 2018, name: "New Years", date: new Date("2018-01-01") }, { _id: 2, year: 2018, name: "Pi Day", date: new Date("2018-03-14") }, { _id: 3, year: 2018, name: "Ice Cream Day", date: new Date("2018-07-15") }, { _id: 4, year: 2017, name: "New Years", date: new Date("2017-01-01") }, { _id: 5, year: 2017, name: "Ice Cream Day", date: new Date("2017-07-16") } ] )
다음 작업은 holidays
컬렉션의 2018년 공휴일 정보와 함께 absences
컬렉션을 조인합니다.
db.absences.aggregate( [ { $lookup: { from: "holidays", pipeline: [ { $match: { year: 2018 } }, { $project: { _id: 0, date: { name: "$name", date: "$date" } } }, { $replaceRoot: { newRoot: "$date" } } ], as: "holidays" } } ] )
이 연산은 다음을 반환합니다:
{ _id: 1, student: 'Ann Aardvark', sickdays: [ ISODate("2018-05-01T00:00:00.000Z"), ISODate("2018-08-23T00:00:00.000Z") ], holidays: [ { name: 'New Years', date: ISODate("2018-01-01T00:00:00.000Z") }, { name: 'Pi Day', date: ISODate("2018-03-14T00:00:00.000Z") }, { name: 'Ice Cream Day', date: ISODate("2018-07-15T00:00:00.000Z") } ] }, { _id: 2, student: 'Zoe Zebra', sickdays: [ ISODate("2018-02-01T00:00:00.000Z"), ISODate("2018-05-23T00:00:00.000Z") ], holidays: [ { name: 'New Years', date: ISODate("2018-01-01T00:00:00.000Z") }, { name: 'Pi Day', date: ISODate("2018-03-14T00:00:00.000Z") }, { name: 'Ice Cream Day', date: ISODate("2018-07-15T00:00:00.000Z") } ] }
이 작업은 다음과 같은 유사 SQL 문장에 해당합니다.
SELECT *, holidays FROM absences WHERE holidays IN ( SELECT name, date FROM holidays WHERE year = 2018 );
자세한 내용은 상관관계가 없는 하위 쿼리 성능 고려 사항을참조하세요.
상관관계가 있는 간결한 하위 쿼리 수행하기 - $lookup
버전 5.0에 추가.
MongoDB 5.0부터 집계 파이프라인 $lookup
단계는 컬렉션 간의 조인을 개선하는 간결한 상관관계 하위 쿼리 구문을 지원합니다. 새로운 간결한 구문은 $match
단계에서 $expr
연산자 내부의 외부 및 로컬 필드에 대한 동등성 매치 요구 사항을 제거합니다.
컬렉션 restaurants
을 만듭니다:
db.restaurants.insertMany( [ { _id: 1, name: "American Steak House", food: [ "filet", "sirloin" ], beverages: [ "beer", "wine" ] }, { _id: 2, name: "Honest John Pizza", food: [ "cheese pizza", "pepperoni pizza" ], beverages: [ "soda" ] } ] )
음식 및 음료 주문(선택 사항)이 포함된 다른 컬렉션 orders
를 만듭니다.
db.orders.insertMany( [ { _id: 1, item: "filet", restaurant_name: "American Steak House" }, { _id: 2, item: "cheese pizza", restaurant_name: "Honest John Pizza", drink: "lemonade" }, { _id: 3, item: "cheese pizza", restaurant_name: "Honest John Pizza", drink: "soda" } ] )
다음 예제입니다.
orders.restaurant_name
localField를restaurants.name
foreignField와 매칭시켜orders
와restaurants
컬렉션을 조인합니다.pipeline
이 실행되기 전에 매치가 수행됩니다.각각
$$orders_drink
및$beverages
를 사용하여 액세스하는orders.drink
및restaurants.beverages
필드 간에$in
배열 일치를 수행합니다.
db.orders.aggregate( [ { $lookup: { from: "restaurants", localField: "restaurant_name", foreignField: "name", let: { orders_drink: "$drink" }, pipeline: [ { $match: { $expr: { $in: [ "$$orders_drink", "$beverages" ] } } } ], as: "matches" } } ] )
orders.drink
및 restaurants.beverages
필드에 soda
값과 일치하는 항목이 있습니다. 이 출력은 matches
배열을 표시하고 일치 항목에 대해 restaurants
컬렉션의 모든 외부 필드를 포함합니다.
{ _id: 1, item: "filet", restaurant_name: "American Steak House", matches: [ ] } { _id: 2, item: "cheese pizza", restaurant_name: "Honest John Pizza", drink: "lemonade", matches: [ ] } { _id: 3, item: "cheese pizza", restaurant_name: "Honest John Pizza", drink: "soda", matches: [ { _id: 2, name": "Honest John Pizza", food: [ "cheese pizza", "pepperoni pizza" ], beverages: [ "soda" ] } ] }
이 예에서는 5.0 이전 버전의 구형 MongoDB 구문을 사용하며 버전에서 앞의 간결한 예와 동일한 결과를 반환합니다.
db.orders.aggregate( [ { $lookup: { from: "restaurants", let: { orders_restaurant_name: "$restaurant_name", orders_drink: "$drink" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: [ "$$orders_restaurant_name", "$name" ] }, { $in: [ "$$orders_drink", "$beverages" ] } ] } } } ], as: "matches" } } ] )
이전 예시는 다음 유사 SQL 문에 해당합니다.
SELECT *, matches FROM orders WHERE matches IN ( SELECT * FROM restaurants WHERE restaurants.name = orders.restaurant_name AND restaurants.beverages = orders.drink );
자세한 내용은 상관관계가 있는 하위 쿼리 성능 고려 사항을 참조하세요.
하위 파이프라인의 네임스페이스
MongoDB 8.0부터 $lookup
및 $unionWith
내의 서브파이프라인의 네임스페이스가 from
및 coll
필드의 올바른 사용을 보장하기 위해 검증됩니다.
$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부터 다음 예시는 잘못된 from
필드를 포함하고 있기 때문에 오류를 반환합니다.
db.cakeFlavors.aggregate( [ { $lookup: { from: "cakeFlavors", pipeline: [ { $documents: [ {} ] } ], as: "test" } } ] )
8.0 이전의 MongoDB 버전에서는 이전 예시 가 실행됩니다.
유효한 from
필드가 있는 예시를 보려면 $lookup
를 사용하여 단일 동등 조인 수행을 참조하세요.
이 페이지의 C# 예제에서는 Atlas 샘플 데이터 세트의 sample_mflix
데이터베이스 사용합니다. 무료 MongoDB Atlas cluster 생성하고 샘플 데이터 세트를 로드하는 방법을 학습하려면 MongoDB .NET/ C# 드라이버 문서에서 시작하기 를 참조하세요.
다음 Movie
클래스는 sample_mflix.movies
컬렉션의 문서를 모델링합니다.
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; } }
참고
파스칼 케이스용 ConventionPack
이 페이지의 C# 클래스는 속성 이름에 파스칼식 대소문자를 사용하지만 MongoDB 컬렉션 의 필드 이름은 카멜식 대소문자를 사용합니다. 이러한 차이를 해소하기 위해 애플리케이션 시작될 때 다음 코드를 사용하여 ConventionPack
를 등록할 수 있습니다.
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
다음 Comment
클래스는 sample_mflix.comments
컬렉션의 문서를 모델링합니다.
public class Comment { public Guid Id { get; set; } [ ] public Guid MovieId { get; set; } public string Text { get; set; } }
MongoDB .NET/ C# 운전자 사용하여 $lookup
집계 파이프라인 에 단계를 추가하려면 PipelineDefinition
객체 에서 Lookup() 메서드를 호출합니다.
다음 예시 movies
컬렉션과 comments
컬렉션 간의 왼쪽 외부 조인을 수행하는 파이프라인 단계를 만듭니다. 이 코드는 각 Movie
문서 의 Id
필드 Comment
문서의 MovieId
필드 에 조인합니다. 각 영화에 대한 댓글은 각 Movie
문서 의 Comments
필드 에 저장됩니다.
var commentCollection = client .GetDatabase("aggregation_examples") .GetCollection<Comment>("comments"); var pipeline = new EmptyPipelineDefinition<Movie>() .Lookup<Movie, Movie, Comment, Movie>( foreignCollection: commentCollection, localField: m => m.Id, foreignField: c => c.MovieId, @as: m => m.Comments);