정의
$graphLookup버전 5.1에서 변경되었습니다.
재귀 깊이 및 쿼리 필터로 검색을 제한하는 옵션을 사용하여 컬렉션에 대해 재귀 검색을 수행합니다.
$graphLookup검색 프로세스가 아래에 요약되어 있습니다.입력 문서는 집계 연산의
$graphLookup단계로 이동합니다.$graphLookup매개변수from으로 지정된 컬렉션으로 검색 대상을 지정합니다.각 입력 문서에 대해 검색은
startWith로 지정된 값으로 시작됩니다.$graphLookupfromcollection의 다른 문서에서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검색 에 대한 작업의 대상 컬렉션
$graphLookupconnectFromFieldconnectToField를 에 재귀적으로 일치시킵니다.from컬렉션 작업에 사용된 다른 컬렉션과 동일한 데이터베이스 에 있어야 합니다.MongoDB 5.1부터
from매개변수에 지정된 컬렉션을 샤딩할 수 있습니다.startWith재귀 검색 시작하는데 사용할 값을 지정하는 표현식입니다.
connectFromFieldstartWith이 배열 로 평가되면$graphLookup는 모든 배열 요소에서 동시에 검색 수행합니다.connectFromField컬렉션 에 있는 다른 문서의 과 재귀적으로 일치시키기
$graphLookup위해 값을 사용하는 필드 이름입니다.connectToField값이 배열 인 경우 각 요소는 순회 프로세스 통해 개별적으로 추적됩니다.connectToFieldconnectFromField매개변수로 지정된 필드의 값과 일치시킬 다른 문서의 필드 이름입니다.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개인 데이터베이스를 만듭니다.
다음 문서가 포함된
airportscollection입니다.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" ] } ] ) 다음 문서가 포함된
travelerscollection입니다: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: Long(2) }, { _id: 2, airport: "ORD", connects: [ "JFK" ], numConnections: Long(1) }, { _id: 1, airport: "BOS", connects: [ "JFK", "PWM" ], numConnections: Long(1) }, { _id: 0, airport: "JFK", connects: [ "BOS", "ORD" ], numConnections: Long(0) } ] } { _id: 2, name: "Eliot", nearestAirport: "JFK", destinations: [ { _id: 3, airport: "PWM", connects: [ "BOS", "LHR" ], numConnections: Long(2) }, { _id: 2, airport: "ORD", connects: [ "JFK" ], numConnections: Long(1) }, { _id: 1, airport: "BOS", connects: [ "JFK", "PWM" ], numConnections: Long(1) }, { _id: 0, airport: "JFK", connects: [ "BOS", "ORD" ], numConnections: Long(0) } ] } { "_id" : 3, name: "Jeff", nearestAirport: "BOS", destinations: [ { _id: 2, airport: "ORD", connects: [ "JFK" ], numConnections: Long(2) }, { _id: 3, airport: "PWM", connects: [ "BOS", "LHR" ], numConnections: Long(1) }, { _id: 4, airport: "LHR", connects: [ "PWM" ], numConnections: Long(2) }, { _id:: 0, airport: "JFK", connects: [ "BOS", "ORD" ], numConnections: Long(1) }, { _id:: 1, airport: "BOS", connects: [ "JFK", "PWM" ], numConnections: Long(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" ] }
0}이라는 이름의 employees 컬렉션에는 다음과 같은 문서가 있습니다:
{ _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" }
다음 Employee 클래스는 employees 컬렉션 의 문서를 모델링합니다.
public class Employee { public ObjectId Id { get; set; } public string Name { get; set; } public Employee ReportsTo { get; set; } public List<Employee> ReportingHierarchy { get; set; } public List<string> Hobbies { get; set; } }
MongoDB .NET/ C# 운전자 사용하여 $graphLookup 집계 파이프라인 에 단계를 추가하려면 PipelineDefinition 객체 에서 GraphLookup() 메서드를 호출합니다.
다음 예시 employees 컬렉션 의 ReportsTo 및 Name 필드에서 재귀적으로 일치하는 파이프라인 단계를 만들어 각 사람에 대한 보고 계층 구조를 반환합니다.
var pipeline = new EmptyPipelineDefinition<Employee>() .GraphLookup<Employee, Employee, Employee, Employee, string, Employee, List<Employee>, Employee>( from: employeeCollection, connectFromField: e => e.ReportsTo, connectToField: e => e.Name, startWith: e => e.ReportsTo, @as: e => e.ReportingHierarchy);
AggregateGraphLookupOptions 객체 사용하여 반복할 깊이와 깊이 필드의 이름을 지정할 수 있습니다. 다음 코드 예시 이전 예시 와 동일한 $graphLookup 작업을 수행하지만 최대 재귀 깊이를 1로 지정합니다.
var employeeCollection = client.GetDatabase("aggregation_examples").GetCollection<Employee>("employees"); var pipeline = new EmptyPipelineDefinition<Employee>() .GraphLookup<Employee, Employee, Employee, Employee, string, Employee, List<Employee>, Employee>( from: employeeCollection, connectFromField: e => e.ReportsTo, connectToField: e => e.Name, startWith: e => e.ReportsTo, @as: e => e.ReportingHierarchy, new AggregateGraphLookupOptions<Employee, Employee, Employee> { MaxDepth = 1 });
AggregateGraphLookupOptions 객체 사용하여 MongoDB 검색 에 문서를 포함하기 위해 문서가 일치해야 하는 필터하다 지정할 수도 있습니다. 다음 코드 예시 이전 예시와 동일한 $graphLookup 작업을 수행하지만, Hobbies 필드 에 "golf"가 포함된 Employee 문서만 포함합니다.
var employeeCollection = client.GetDatabase("aggregation_examples").GetCollection<Employee>("employees"); var pipeline = new EmptyPipelineDefinition<Employee>() .GraphLookup<Employee, Employee, Employee, Employee, string, Employee, List<Employee>, Employee>( from: employeeCollection, connectFromField: e => e.ReportsTo, connectToField: e => e.Name, startWith: e => e.ReportsTo, @as: e => e.ReportingHierarchy, new AggregateGraphLookupOptions<Employee, Employee, Employee> { MaxDepth = 1, RestrictSearchWithMatch = Builders<Employee>.Filter.AnyEq(e => e.Hobbies, "golf") });
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" } ]);
MongoDB Node.js 운전자 사용하여 집계 파이프라인 에 $graphLookup 단계를 추가하려면 파이프라인 객체 에서 $graphLookup 연산자 사용합니다.
다음 예시는 employees 컬렉션의 name 필드와 reportsTo 필드를 재귀적으로 일치시켜, reportingHierarchy라는 새 필드에 각 사용자의 보고 계층 구조를 반환하는 파이프라인 단계를 만듭니다. 그리고 집계 파이프라인을 실행합니다.
const pipeline = [ { $graphLookup: { from: "employees", connectFromField: "reportsTo", connectToField: "name", startWith: "$reportsTo", as: "reportingHierarchy" } } ]; const cursor = collection.aggregate(pipeline); return cursor;
재귀 깊이를 지정하려면 maxDepth 필드를 사용합니다. 다음 코드 예시는 이전 예시와 동일한 $graphLookup 작업을 수행하지만, 최대 재귀 깊이를 1로 지정합니다.
const pipeline = [ { $graphLookup: { from: "employees", connectFromField: "reportsTo", connectToField: "name", startWith: "$reportsTo", as: "reportingHierarchy", maxDepth: 1 } } ]; const cursor = collection.aggregate(pipeline); return cursor;
작업에서 문서를 검색 결과에 포함시키기 위해 문서가 일치해야 하는 필터를 지정하려면 restrictSearchWithMatch 필드를 사용합니다. 다음 코드 예시는 이전 예시와 동일한 $graphLookup 작업을 수행하지만, hobbies 필드에 "golf"가 포함된 employee 문서만 포함합니다.
const pipeline = [ { $graphLookup: { from: "employees", connectFromField: "reportsTo", connectToField: "name", startWith: "$reportsTo", as: "reportingHierarchy", maxDepth: 1, restrictSearchWithMatch: { hobbies: "golf" } } } ]; const cursor = collection.aggregate(pipeline); return cursor;
자세히 알아보기
$graphLookup 사용 방법을 자세히 알아보려면 웨비나: MongoDB에서 그래프 데이터로 작업하기를 참조하세요.