Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ / /

$graphLookup (집계)

이 페이지의 내용

  • 정의
  • 고려 사항
  • 예시
  • 추가 리소스

버전 3.4에서 변경됨.

$graphLookup

재귀 깊이 및 쿼리 필터로 검색을 제한하는 옵션을 사용하여 컬렉션에 대해 재귀 검색을 수행합니다.

$graphLookup 검색 프로세스가 아래에 요약되어 있습니다.

  1. 입력 문서는 집계 연산의 $graphLookup 단계로 이동합니다.

  2. $graphLookup 매개변수 from으로 지정된 컬렉션으로 검색 대상을 지정합니다.

  3. 각 입력 문서에 대해 검색은 startWith로 지정된 값으로 시작됩니다.

  4. $graphLookup from collection의 다른 문서에서 connectToField(으)로 지정된 필드와 startWith 값을 일치시킵니다.

  5. 일치하는 각 문서에서 $graphLookupconnectFromField 값을 가져와 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로 지정하고, connectFromFieldconnectToField 에 재귀적으로 일치시킵니다. from 컬렉션은 샤딩할 수 없으며 작업에 사용된 다른 컬렉션과 동일한 데이터베이스에 있어야 합니다. 자세한 내용은 샤드 컬렉션을 참조하세요.
startWith
재귀 검색을 시작할 때 사용할 connectFromField 값을 지정하는 표현식입니다. 선택적으로, startWith는 값의 배열일 수 있으며, 각 값은 순회 프로세스를 통해 개별적으로 추적됩니다.
connectFromField
컬렉션에 있는 다른 문서의 connectToField와 재귀적으로 일치시키기 위해 $graphLookup 값을 사용하는 필드 이름입니다. 값이 배열인 경우 각 요소는 순회 프로세스를 통해 개별적으로 추적됩니다.
connectToField
connectFromField 매개변수로 지정된 필드의 값과 일치시킬 다른 문서의 필드 이름입니다.
as

각 출력 문서에 추가된 배열 필드의 이름입니다. 문서에 도달하기 위해 $graphLookup 단계에서 탐색한 문서를 포함합니다.

as 필드에 반환된 문서가 어떤 순서로 정렬되는지 보장되지 않습니다.

maxDepth
선택 사항입니다. 최대 재귀 깊이를 지정하는 음수가 아닌 정수입니다.
depthField
선택 사항. 검색 경로에서 탐색된 각각의 문서에 추가할 필드의 이름입니다. 이 필드의 값은 문서의 재귀 깊이이며, NumberLong으로 표시됩니다. 재귀 깊이 값은 0에서 시작하므로 첫 번째 조회는 깊이 0에 해당합니다.
restrictSearchWithMatch

선택 사항. 재귀 검색에 대한 추가 조건을 지정하는 문서입니다. 구문은 쿼리 필터 구문과 동일합니다.

이 필터에는 집계 표현식 을 사용할 수 없습니다. 예를 들어, 다음 문서를 사용하여 lastName 값이 입력 문서의 lastName 값과 다른 문서를 찾을 수 없습니다.

{ lastName: { $ne: "$lastName" } }

"$lastName" 는 필드 경로가 아니라 string 리터럴로 작동하므로 이 컨텍스트에서는 문서를 사용할 수 없습니다.

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 등 여러 뷰가 포함된 집계를 수행하는 경우 반드시 뷰의 데이터 정렬이 동일해야 합니다.

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" }에 대한 순회 경로를 제공합니다.

시작 값

문서의 reportsTo 값입니다.

{ ... reportsTo: "Ron" }
깊이 0
{ _id: 3, name: "Ron", reportsTo: "Eliot" }
깊이 1
{ _id: 2, name: "Eliot", reportsTo: "Dev" }
깊이 2
{ _id: 1, name: "Dev" }

출력은 계층 구조 Asya -> Ron -> Eliot -> Dev을(를) 생성합니다.

$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 깊이까지 재귀 검색을 위한 순회 경로를 제공합니다. 여기서 시작 airportJFK입니다.

시작 값

travelers 컬렉션의 nearestAirport 값입니다.

{ ... nearestAirport: "JFK" }
깊이 0
{ _id: 0, airport: "JFK", connects: [ "BOS", "ORD" ] }
깊이 1
{ _id: 1, airport: "BOS", connects: [ "JFK", "PWM" ] }
{ _id: 2, airport: "ORD", connects: [ "JFK" ] }
깊이 2
{ _id: 3, airport: "PWM", connects: [ "BOS", "LHR" ] }

다음 예시에서는 사람들의 이름과 함께 친구 및 취미 배열이 포함된 문서 세트가 있는 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"
]
}

웨비나: MongoDB에서 그래프 데이터로 작업하기

돌아가기

$geoNear