$graphLookup (집계)
버전 3.4에서 변경됨.
정의
$graphLookup
재귀 깊이 및 쿼리 필터로 검색을 제한하는 옵션을 사용하여 컬렉션에 대해 재귀 검색을 수행합니다.
$graphLookup
검색 프로세스가 아래에 요약되어 있습니다.입력 문서는 집계 연산의
$graphLookup
단계로 이동합니다.$graphLookup
매개변수from
으로 지정된 컬렉션으로 검색 대상을 지정합니다.각 입력 문서에 대해 검색은
startWith
로 지정된 값으로 시작됩니다.$graphLookup
from
collection의 다른 문서에서connectToField
(으)로 지정된 필드와startWith
값을 일치시킵니다.일치하는 각 문서에서
$graphLookup
은connectFromField
값을 가져와from
컬렉션 내 모든 문서에서 일치하는connectToField
값이 있는지 확인합니다. 각$graphLookup
일치 항목에from
대해 collection의 일치하는 문서를 매개변수로 명명된 배열as
필드에 추가합니다.이 단계는 일치하는 문서를 더 이상 찾을 수 없거나 작업이
maxDepth
매개 변수로 지정된 재귀 깊이에 도달할 때까지 재귀적으로 계속됩니다.$graphLookup
은(는) 입력 문서에 배열 필드를 추가합니다.$graphLookup
은(는) 모든 입력 문서에 대한 검색을 완료한 후 결과를 반환합니다.
$graphLookup
의 프로토타입 형태는 다음과 같습니다:{ $graphLookup: { from: <collection>, startWith: <expression>, connectFromField: <string>, connectToField: <string>, as: <string>, maxDepth: <number>, depthField: <string>, restrictSearchWithMatch: <document> } } $graphLookup
은 다음 필드가 있는 문서를 가져옵니다.필드설명from
$graphLookup
작업에 대한 컬렉션을 Atlas Search로 지정하고,connectFromField
를connectToField
에 재귀적으로 일치시킵니다.from
컬렉션은 샤딩할 수 없으며 작업에 사용된 다른 컬렉션과 동일한 데이터베이스에 있어야 합니다. 자세한 내용은 샤드 컬렉션을 참조하세요.startWith
재귀 검색을 시작할 때 사용할connectFromField
값을 지정하는 표현식입니다. 선택적으로,startWith
는 값의 배열일 수 있으며, 각 값은 순회 프로세스를 통해 개별적으로 추적됩니다.connectFromField
컬렉션에 있는 다른 문서의connectToField
와 재귀적으로 일치시키기 위해$graphLookup
값을 사용하는 필드 이름입니다. 값이 배열인 경우 각 요소는 순회 프로세스를 통해 개별적으로 추적됩니다.connectToField
connectFromField
매개변수로 지정된 필드의 값과 일치시킬 다른 문서의 필드 이름입니다.as
각 출력 문서에 추가된 배열 필드의 이름입니다. 문서에 도달하기 위해
$graphLookup
단계에서 탐색한 문서를 포함합니다.as
필드에 반환된 문서가 어떤 순서로 정렬되는지 보장되지 않습니다.maxDepth
선택 사항입니다. 최대 재귀 깊이를 지정하는 음수가 아닌 정수입니다.depthField
선택 사항. 검색 경로에서 탐색된 각각의 문서에 추가할 필드의 이름입니다. 이 필드의 값은 문서의 재귀 깊이이며,NumberLong
으로 표시됩니다. 재귀 깊이 값은 0에서 시작하므로 첫 번째 조회는 깊이 0에 해당합니다.restrictSearchWithMatch
고려 사항
샤드 컬렉션
from
에 지정된 컬렉션은 샤딩 할 수 없습니다. 그러나 aggregate()
메서드를 실행하는 컬렉션은 샤딩할 수 있습니다. 즉, 다음에서:
db.collection.aggregate([ { $graphLookup: { from: "fromCollection", ... } } ])
collection
을(를) 샤딩할 수 있습니다.fromCollection
는 샤딩할 수 없습니다.
여러 샤드 컬렉션을 조인하려면 다음을 고려하세요.
$graphLookup
애그리게이션 단계를 사용하는 대신 수동 조회를 수행하도록 클라이언트 애플리케이션을 수정합니다.가능하면 컬렉션을 조인할 필요가 없는 내장된 데이터 모델 을 사용합니다.
최대 깊이
maxDepth
필드를 0
으로 설정하는 것은 비재귀 $graphLookup
검색 단계와 동일합니다.
메모리
$graphLookup
단계는 100 메가바이트 메모리 제한 내에 있어야 합니다. aggregate()
연산에 대해 allowDiskUse: true
가 지정된 경우 $graphLookup
단계는 이 옵션을 무시합니다. aggregate()
연산에 다른 단계가 있는 경우 이러한 다른 단계에는 allowDiskUse: true
옵션이 적용됩니다.
자세한 내용은 애그리게이션 파이프라인 제한 사항을 참조하세요.
보기 및 데이터 정렬
$lookup
또는 $graphLookup
등 여러 뷰가 포함된 집계를 수행하는 경우 반드시 뷰의 데이터 정렬이 동일해야 합니다.
예시
단일 collection 내에서
0}이라는 이름의 employees
컬렉션에는 다음과 같은 문서가 있습니다:
db.employees.insertMany( [ { _id: 1, name: "Dev" }, { _id: 2, name: "Eliot", reportsTo: "Dev" }, { _id: 3, name: "Ron", reportsTo: "Eliot" }, { _id: 4, name: "Andrew", reportsTo: "Eliot" }, { _id: 5, name: "Asya", reportsTo: "Ron" }, { _id: 6, name: "Dan", reportsTo: "Andrew" } ] )
다음 $graphLookup
작업은 employees
컬렉션의 reportsTo
, name
필드에서 재귀적으로 일치해 각 사용자에 대한 보고 계층 구조를 반환합니다.
db.employees.aggregate( [ { $graphLookup: { from: "employees", startWith: "$reportsTo", connectFromField: "reportsTo", connectToField: "name", as: "reportingHierarchy" } } ] )
이 연산은 다음을 반환합니다:
{ _id: 1, name: "Dev", reportingHierarchy: [ ] } { _id: 2, name: "Eliot", reportsTo: "Dev", reportingHierarchy : [ { _id: 1, name: "Dev" } ] } { _id: 3, name: "Ron", reportsTo: "Eliot", reportingHierarchy: [ { _id: 2, name: "Eliot", reportsTo: "Dev" }, { _id: 1, name: "Dev" } ] } { _id: 4, name: "Andrew", reportsTo: "Eliot", reportingHierarchy: [ { _id: 2, name: "Eliot", reportsTo: "Dev" }, { _id: 1, name: "Dev" } ] } { _id: 5, name: "Asya", reportsTo: "Ron", reportingHierarchy: [ { _id: 2, name: "Eliot", reportsTo: "Dev" }, { _id: 3, name: "Ron", reportsTo: "Eliot" }, { _id: 1, name: "Dev" } ] } { "_id" : 6, "name" : "Dan", "reportsTo" : "Andrew", "reportingHierarchy" : [ { _id: 4, name: "Andrew", reportsTo: "Eliot" }, { _id: 2, name: "Eliot", reportsTo: "Dev" }, { _id: 1, name: "Dev" } ] }
다음 표는 문서 { "_id" : 5, "name" : "Asya", "reportsTo" : "Ron" }
에 대한 순회 경로를 제공합니다.
시작 값 | 문서의
| |
깊이 0 |
| |
깊이 1 |
| |
깊이 2 |
|
출력은 계층 구조 Asya -> Ron -> Eliot -> Dev
을(를) 생성합니다.
여러 collection에 걸쳐
$lookup
과 마찬가지로 $graphLookup
은 동일한 데이터베이스의 다른 컬렉션에 액세스할 수 있습니다.
예를 들어, 컬렉션이 2개인 데이터베이스를 만듭니다.
다음 문서가 포함된
airports
collection입니다.db.airports.insertMany( [ { _id: 0, airport: "JFK", connects: [ "BOS", "ORD" ] }, { _id: 1, airport: "BOS", connects: [ "JFK", "PWM" ] }, { _id: 2, airport: "ORD", connects: [ "JFK" ] }, { _id: 3, airport: "PWM", connects: [ "BOS", "LHR" ] }, { _id: 4, airport: "LHR", connects: [ "PWM" ] } ] ) 다음 문서가 포함된
travelers
collection입니다:db.travelers.insertMany( [ { _id: 1, name: "Dev", nearestAirport: "JFK" }, { _id: 2, name: "Eliot", nearestAirport: "JFK" }, { _id: 3, name: "Jeff", nearestAirport: "BOS" } ] )
다음 집계 작업은 travelers
컬렉션의 각 문서에 대해 airports
컬렉션에서 nearestAirport
값을 조회하고 connects
필드를 airport
필드와 재귀적으로 일치시킵니다. 이 작업은 최대 재귀 깊이를 2
로 지정합니다.
db.travelers.aggregate( [ { $graphLookup: { from: "airports", startWith: "$nearestAirport", connectFromField: "connects", connectToField: "airport", maxDepth: 2, depthField: "numConnections", as: "destinations" } } ] )
이 연산은 다음과 같은 결과를 반환합니다.
{ _id: 1, name: "Dev", nearestAirport: "JFK", destinations: [ { _id: 3, airport: "PWM", connects: [ "BOS", "LHR" ], numConnections: NumberLong(2) }, { _id: 2, airport: "ORD", connects: [ "JFK" ], numConnections: NumberLong(1) }, { _id: 1, airport: "BOS", connects: [ "JFK", "PWM" ], numConnections: NumberLong(1) }, { _id: 0, airport: "JFK", connects: [ "BOS", "ORD" ], numConnections: NumberLong(0) } ] } { _id: 2, name: "Eliot", nearestAirport: "JFK", destinations: [ { _id: 3, airport: "PWM", connects: [ "BOS", "LHR" ], numConnections: NumberLong(2) }, { _id: 2, airport: "ORD", connects: [ "JFK" ], numConnections: NumberLong(1) }, { _id: 1, airport: "BOS", connects: [ "JFK", "PWM" ], numConnections: NumberLong(1) }, { _id: 0, airport: "JFK", connects: [ "BOS", "ORD" ], numConnections: NumberLong(0) } ] } { "_id" : 3, name: "Jeff", nearestAirport: "BOS", destinations: [ { _id: 2, airport: "ORD", connects: [ "JFK" ], numConnections: NumberLong(2) }, { _id: 3, airport: "PWM", connects: [ "BOS", "LHR" ], numConnections: NumberLong(1) }, { _id: 4, airport: "LHR", connects: [ "PWM" ], numConnections: NumberLong(2) }, { _id:: 0, airport: "JFK", connects: [ "BOS", "ORD" ], numConnections: NumberLong(1) }, { _id:: 1, airport: "BOS", connects: [ "JFK", "PWM" ], numConnections: NumberLong(0) } ] }
다음 표는 최대 2
깊이까지 재귀 검색을 위한 순회 경로를 제공합니다. 여기서 시작 airport
은 JFK
입니다.
시작 값 |
| ||
깊이 0 |
| ||
깊이 1 |
| ||
깊이 2 |
|
쿼리 필터 사용
다음 예시에서는 사람들의 이름과 함께 친구 및 취미 배열이 포함된 문서 세트가 있는 collection을 사용합니다. 집계 작업은 특정 사람 한 명을 찾고 그 사람의 연결 네트워크를 탐색하여 취미에 golf
을(를) 기재한 사람을 찾습니다.
people
라는 이름의 컬렉션에 다음 문서가 포함되어 있습니다.
db.people.insertMany( [ { _id: 1, name: "Tanya Jordan", friends: [ "Shirley Soto", "Terry Hawkins", "Carole Hale" ], hobbies: [ "tennis", "unicycling", "golf" ] }, { _id: 2, name: "Carole Hale", friends: [ "Joseph Dennis", "Tanya Jordan", "Terry Hawkins" ], hobbies: [ "archery", "golf", "woodworking" ] }, { _id: 3, name: "Terry Hawkins", friends: [ "Tanya Jordan", "Carole Hale", "Angelo Ward" ], hobbies: [ "knitting", "frisbee" ] }, { _id: 4, name: "Joseph Dennis", friends: [ "Angelo Ward", "Carole Hale" ], hobbies: [ "tennis", "golf", "topiary" ] }, { _id: 5, name: "Angelo Ward", friends: [ "Terry Hawkins", "Shirley Soto", "Joseph Dennis" ], hobbies: [ "travel", "ceramics", "golf" ] }, { _id: 6, name: "Shirley Soto", friends: [ "Angelo Ward", "Tanya Jordan", "Carole Hale" ], hobbies: [ "frisbee", "set theory" ] } ] )
다음 집계 작업은 세 단계를 사용합니다.
$match
는"Tanya Jordan"
문자열을 포함한name
필드가 있는 문서와 일치합니다. 하나의 출력 문서를 반환합니다.$graphLookup
은 출력 문서의friends
필드를 컬렉션에 있는 다른 문서의name
필드와 연결하여Tanya Jordan's
연결 네트워크를 순회합니다. 이 단계에서는restrictSearchWithMatch
매개 변수를 사용하여hobbies
배열에golf
가 포함된 문서만 찾습니다. 출력 문서 한 개를 반환합니다.$project
는 출력 문서의 형태를 지정합니다.connections who play golf
목록에 있는 이름은 입력 문서의golfers
배열에 나열된 문서의name
필드에서 가져온 것입니다.
db.people.aggregate( [ { $match: { "name": "Tanya Jordan" } }, { $graphLookup: { from: "people", startWith: "$friends", connectFromField: "friends", connectToField: "name", as: "golfers", restrictSearchWithMatch: { "hobbies" : "golf" } } }, { $project: { "name": 1, "friends": 1, "connections who play golf": "$golfers.name" } } ] )
연산은 다음 문서를 반환합니다.
{ _id: 1, name: "Tanya Jordan", friends: [ "Shirley Soto", "Terry Hawkins", "Carole Hale" ], 'connections who play golf': [ "Joseph Dennis", "Tanya Jordan", "Angelo Ward", "Carole Hale" ] }