$graphLookup (집계)
정의
$graphLookup
버전 5.1에서 변경되었습니다.
재귀 깊이 및 쿼리 필터로 검색을 제한하는 옵션을 사용하여 컬렉션에 대해 재귀 검색을 수행합니다.
$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
대상 컬렉션connectFromField
connectToField
으로, 를 에 재귀적으로 일치시킵니다.from
컬렉션 은 작업에 사용된 다른 컬렉션과 동일한 데이터베이스 에 있어야 합니다.MongoDB 5.1부터
from
매개변수에 지정된 컬렉션을 샤딩할 수 있습니다.startWith
재귀 검색 을 시작하는 데 사용할 값을 지정하는 표현식입니다. 이배열 로
connectFromField
startWith
평가되면$graphLookup
는 모든 배열 요소에서 동시에 검색 을 수행합니다.connectFromField
컬렉션 에 있는 다른 문서의 과 재귀적으로 일치시키기
$graphLookup
위해 값을 사용하는 필드 이름입니다. 값이 배열 인 경우 각 요소는 순회 프로세스 를 통해 개별적으로 추적됩니다.connectToField
connectToField
connectFromField
매개변수로 지정된 필드의 값과 일치시킬 다른 문서의 필드 이름입니다.as
각 출력 문서 에 추가된 배열 필드 의 이름입니다. 문서에 도달하기 위해 단계에서 탐색한 문서 를 포함합니다.
$graphLookup
as
필드에 반환된 문서가 어떤 순서로 정렬되는지 보장되지 않습니다.maxDepth
선택 사항입니다. 최대 재귀 깊이를 지정하는 음수가 아닌 정수입니다.
depthField
선택 사항. 검색 경로에서 탐색된 각각의 문서에 추가할 필드의 이름입니다. 이 필드의 값은 문서의 재귀 깊이이며,
NumberLong
으로 표시됩니다. 재귀 깊이 값은 0에서 시작하므로 첫 번째 조회는 깊이 0에 해당합니다.restrictSearchWithMatch
고려 사항
샤드 컬렉션
MongoDB 5.1부터 $graphLookup
단계의 from
파라미터에서 샤딩된 컬렉션을 지정할 수 있습니다.
샤딩된 컬렉션을 대상으로 하는 동안 트랜잭션 내에서 $graphLookup
단계를 사용할 수 없습니다.
최대 깊이
maxDepth
필드를 0
으로 설정하는 것은 비재귀 $graphLookup
검색 단계와 동일합니다.
메모리
$graphLookup
단계는 100 메가바이트 메모리 제한 내에 있어야 합니다. aggregate()
연산에 대해 allowDiskUse: true
가 지정된 경우 $graphLookup
단계는 이 옵션을 무시합니다. aggregate()
연산에 다른 단계가 있는 경우 이러한 다른 단계에는 allowDiskUse: true
옵션이 적용됩니다.
자세한 내용은 애그리게이션 파이프라인 제한 사항을 참조하세요.
정렬되지 않은 결과
$graphLookup
단계는 정렬된 결과를 반환하지 않습니다. 결과를 정렬하려면 연산자 를 $sortArray
사용합니다.
보기 및 데이터 정렬
$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" ] }