View a markdown version of this page

$graphLookup - Amazon DocumentDB

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

$graphLookup

버전 8.0.2에서 새로 추가되었습니다.

Amazon DocumentDB의 $graphLookup 집계 단계는 컬렉션에 대한 재귀 검색을 수행합니다. 각 입력 문서에 대해는 하나 이상의 값에서 $graphLookup 시작하여 일치하는 문서가 더 이상 없거나 선택적 재귀 깊이에 도달할 때까지 일치하는 문서 체인에 따라 연결 필드를 대상 필드와 반복적으로 일치시킵니다. 이는 조직 보고 구조, 범주 트리 또는 네트워크 관계와 같은 그래프형 또는 계층적 데이터를 통과하는 데 유용합니다.

파라미터

  • from: 재귀적으로 검색할 대상 컬렉션입니다. from 모음은 동일한 데이터베이스에 있어야 합니다.

  • startWith: 재귀 검색을 시작할 값을 지정하는 표현식입니다. 이 값은 from 컬렉션에 있는 문서의 connectToField와 비교됩니다. 가 배열로 startWith 평가되면 검색은 모든 배열 요소에서 동시에 실행됩니다.

  • connectFromField: 값이 재귀 검색에서 다음 문서에 연결하는 데 사용되는 필드 이름입니다. 값이 배열인 경우 각 요소는 순회를 통해 개별적으로 추적됩니다.

  • connectToField:의 값과 일치하는 from 컬렉션의 필드 이름입니다connectFromField.

  • as: 각 출력 문서에 추가된 배열 필드의 이름입니다. 이 필드에는 재귀 검색 중에 찾은 문서가 포함되어 있습니다. 이러한 문서의 순서에 대한 자세한 내용은 다음 동작 섹션의 결과 순서 항목을 참조하세요.

  • maxDepth: 초기 조회 후 수행할 최대 재귀 반복 횟수를 지정하는 음수가 아닌 정수입니다. 이 파라미터는 선택 사항입니다. 값은 초기 일치만 0 수행하고 재귀는 수행하지 않습니다. maxDepth를 생략하면 일치하는 문서가 더 이상 없을 때까지 검색이 재귀적으로 계속됩니다.

  • depthField: 문서가 발견된 재귀 깊이를 포함하는 as 배열의 각 문서에 추가할 필드의 이름입니다. 이 파라미터는 선택 사항입니다. 깊이는 로 표시되고 0부터 NumberLong 시작하므로 초기 조회는 깊이에 해당합니다0.

  • restrictSearchWithMatch: 검색 문서에 적용되는 추가 일치 조건을 지정하는 문서입니다. 이 파라미터는 선택 사항입니다. 조건은 $match 스테이지와 동일한 쿼리 구문을 사용하며 집계 표현식을 포함할 수 없습니다.

참고

$graphLookup 스테이지에는 100MB 메모리 제한이 적용되며를 지원하지 않습니다allowDiskUse:true. 이 제한을 초과하는 작업은 오류를 반환합니다. 집계에 다른 단계가 포함된 경우 allowDiskUse:true 옵션은 해당 단계에 적용됩니다.

동작

  • 컬렉션 간 순회: 검색하려는 컬렉션from으로 설정합니다. 파이프라인이 실행되는 것과 동일한 컬렉션 또는 동일한 데이터베이스의 다른 컬렉션일 수 있습니다.

  • 결과 순서 지정: as 배열의 문서는 어떤 보장된 순서로도 반환되지 않습니다.

예제(MongoDB 쉘)

다음 예제에서는 $graphLookup를 사용하여 직원 보고 계층 구조를 통과하고 각 직원에 대해 위의 전체 관리자 체인을 반환합니다.

다음 명령은 mongosh 셸에서 실행되고 보고 계층 구조를 설정하는 샘플 직원 문서를 삽입합니다.

db.employees.insertMany([ { _id: 1, name: "Dev", reportsTo: "Eliot" }, { _id: 2, name: "Eliot", reportsTo: "Ron" }, { _id: 3, name: "Ron", reportsTo: "Andrew" }, { _id: 4, name: "Andrew", reportsTo: "Asya" }, { _id: 5, name: "Asya" } ]);

다음 집계는 새 reportingHierarchy 배열의 각 직원에 대한 전체 관리 체인을 반환합니다.

db.employees.aggregate([ { $graphLookup: { from: "employees", startWith: "$reportsTo", connectFromField: "reportsTo", connectToField: "name", as: "reportingHierarchy", depthField: "level" } } ]);

이 작업은 다음 출력을 반환합니다.

[ { _id: 1, name: 'Dev', reportsTo: 'Eliot', reportingHierarchy: [ { _id: 2, name: 'Eliot', reportsTo: 'Ron', level: 0 }, { _id: 3, name: 'Ron', reportsTo: 'Andrew', level: 1 }, { _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 2 }, { _id: 5, name: 'Asya', level: 3 } ] }, { _id: 2, name: 'Eliot', reportsTo: 'Ron', reportingHierarchy: [ { _id: 3, name: 'Ron', reportsTo: 'Andrew', level: 0 }, { _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 1 }, { _id: 5, name: 'Asya', level: 2 } ] }, { _id: 3, name: 'Ron', reportsTo: 'Andrew', reportingHierarchy: [ { _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 0 }, { _id: 5, name: 'Asya', level: 1 } ] }, { _id: 4, name: 'Andrew', reportsTo: 'Asya', reportingHierarchy: [ { _id: 5, name: 'Asya', level: 0 } ] }, { _id: 5, name: 'Asya', reportingHierarchy: [] } ]

각 직원 문서는 재귀적으로 일치하는 관리자 문서가 포함된 reportingHierarchy 배열을 얻습니다. level 필드는 각 관리자가 발견된 재귀 깊이를 기록합니다. Asya에는 reportsTo 값이 없으므로 reportingHierarchy 배열이 비어 있습니다.

maxDepth 및 restrictSearchWithMatch를 사용한 예제(MongoDB Shell)

다음 예제에서는 사람 간의 연결 네트워크를 통과하고를 사용하여 재귀maxDepth를 제한하고 추가 조건과 일치하는 문서만 restrictSearchWithMatch 포함합니다. 검색은 시작하는 사람의 연결을 최대 두 수준 깊이까지 찾아 hobbies 배열에가 포함된 사람만 유지합니다golf.

다음 명령은 mongosh 셸에서 실행되며 각 사람이 단방향 연결 체인을 통해 앞으로 friends 가리키는 샘플 문서를 삽입합니다.

db.people.insertMany([ { _id: 1, name: "Tanya", friends: [ "Carole", "Shirley" ], hobbies: [ "tennis", "golf" ] }, { _id: 2, name: "Carole", friends: [ "Joseph" ], hobbies: [ "archery", "golf" ] }, { _id: 3, name: "Joseph", friends: [ "Angelo" ], hobbies: [ "tennis", "golf" ] }, { _id: 4, name: "Angelo", friends: [ "Miguel" ], hobbies: [ "travel", "golf" ] }, { _id: 5, name: "Miguel", friends: [], hobbies: [ "golf" ] }, { _id: 6, name: "Shirley", friends: [], hobbies: [ "frisbee" ] } ]);

다음 집계는 Tanya에서 시작하여 최대 두 레벨 깊이까지 연결 네트워크를 통과하고를 취미golf로 나열하는 사람만 유지합니다.

db.people.aggregate([ { $match: { name: "Tanya" } }, { $graphLookup: { from: "people", startWith: "$friends", connectFromField: "friends", connectToField: "name", as: "golfConnections", maxDepth: 2, restrictSearchWithMatch: { hobbies: "golf" } } }, { $project: { name: 1, "golfConnections.name": 1 } } ]);

이 작업은 다음 출력을 반환합니다.

[ { _id: 1, name: 'Tanya', golfConnections: [ { name: 'Carole' }, { name: 'Joseph' }, { name: 'Angelo' } ] } ]

hobbies 배열에 포함된 연결만 포함되며 두 수준의 재귀 후 순회가 중지golf됩니다. Shirley는를 나열하지 않기 때문에 제외golf되고 Miguel은 maxDepth의를 넘어 Tanya에서 3개 레벨 떨어져 있기 때문에 제외됩니다2. 연결은 Tanya를 가리키지 않는 단방향 체인을 구성하므로 재귀 검색 중에 시작 문서가 일치하지 않습니다.

코드 예제

MongoDB 드라이버를 사용하여 첫 번째 예제에서 직원 보고 계층 구조를 빌드하는 코드 예제를 보려면 사용하려는 언어의 탭을 선택합니다.

Node.js
const { MongoClient } = require('mongodb'); async function example() { const client = new MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'); try { await client.connect(); const db = client.db('test'); const employees = db.collection('employees'); const result = await employees.aggregate([ { $graphLookup: { from: 'employees', startWith: '$reportsTo', connectFromField: 'reportsTo', connectToField: 'name', as: 'reportingHierarchy', depthField: 'level' } } ]).toArray(); console.log(JSON.stringify(result, null, 2)); } catch (err) { console.error('Failed to run $graphLookup aggregation:', err.message); } finally { await client.close(); } } example();
Python
from pymongo import MongoClient from pymongo.errors import PyMongoError def example(): client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') try: db = client['test'] employees = db['employees'] pipeline = [ { "$graphLookup": { "from": "employees", "startWith": "$reportsTo", "connectFromField": "reportsTo", "connectToField": "name", "as": "reportingHierarchy", "depthField": "level" } } ] result = list(employees.aggregate(pipeline)) for doc in result: print(doc) except PyMongoError as error: print(f"Failed to run $graphLookup aggregation: {error}") finally: client.close() example()