$graphLookup (aggregation)
On this page本页内容
Definition定义
$graphLookup
Changed in version 5.1.5.1版更改。Performs a recursive search on a collection, with options for restricting the search by recursion depth and query filter.对集合执行递归搜索,并提供按递归深度和查询筛选器限制搜索的选项。The$graphLookup
search process is summarized below:$graphLookup
搜索过程总结如下:Input documents flow into the输入文档流入聚合操作的$graphLookup
stage of an aggregation operation.$graphLookup
阶段。$graphLookup
targets the search to the collection designated by the将搜索目标定为from
parameter (see below for full list of search parameters).from
参数指定的集合(有关搜索参数的完整列表,请参阅下文)。For each input document, the search begins with the value designated by对于每个输入文档,搜索从startWith
.startWith
指定的值开始。$graphLookup
matches the将startWith
value against the field designated byconnectToField
in other documents in thefrom
collection.startWith
值与from
集合中其他文档中connectToField
指定的字段相匹配。For each matching document,对于每个匹配的文档,$graphLookup
takes the value of theconnectFromField
and checks every document in thefrom
collection for a matchingconnectToField
value.$graphLookup
获取connectFromField
的值,并在from
集合中的每个文档中检查匹配的connectToField
值。For each match,对于每个匹配,$graphLookup
adds the matching document in thefrom
collection to an array field named by theas
parameter.$graphLookup
将from
集合中的匹配文档添加到由as
参数命名的数组字段中。This step continues recursively until no more matching documents are found, or until the operation reaches a recursion depth specified by the此步骤将递归地继续,直到找不到更多匹配的文档,或者直到操作达到maxDepth
parameter.maxDepth
参数指定的递归深度。$graphLookup
then appends the array field to the input document.然后将数组字段附加到输入文档中。$graphLookup
returns results after completing its search on all input documents.在完成对所有输入文档的搜索后返回结果。
$graphLookup
has the following prototype form:具有以下原型形式:{
$graphLookup: {
from: <collection>,
startWith: <expression>,
connectFromField: <string>,
connectToField: <string>,
as: <string>,
maxDepth: <number>,
depthField: <string>,
restrictSearchWithMatch: <document>
}
}$graphLookup
takes a document with the following fields:获取具有以下字段的文档:Field字段Description描述from
Target collection for the要搜索的$graphLookup
operation to search, recursively matching theconnectFromField
to theconnectToField
.$graphLookup
操作的目标集合,递归地将connectFromField
与connectToField
匹配。Thefrom
collection must be in the same database as any other collections used in the operation.from
集合必须与操作中使用的任何其他集合位于同一数据库中。
Starting in MongoDB 5.1, the collection specified in the从MongoDB 5.1开始,可以对from
parameter can be sharded.from
参数中指定的集合进行分片。startWith
Expression that specifies the value of the表达式,指定用于启动递归搜索的connectFromField
with which to start the recursive search.connectFromField
的值。Optionally,可选地,startWith
may be array of values, each of which is individually followed through the traversal process.startWith
可以是值的数组,每个值在遍历过程中都单独跟随。connectFromField
Field name whose value字段名,其值$graphLookup
uses to recursively match against theconnectToField
of other documents in the collection.$graphLookup
用于递归匹配集合中其他文档的connectToField
。If the value is an array, each element is individually followed through the traversal process.如果该值是一个数组,则每个元素都将在遍历过程中单独跟随。connectToField
Field name in other documents against which to match the value of the field specified by the与connectFromField
parameter.connectFromField
参数指定的字段值匹配的其他文档中的字段名称。as
Name of the array field added to each output document.添加到每个输出文档的数组字段的名称。Contains the documents traversed in the包含在$graphLookup
stage to reach the document.$graphLookup
阶段中为访问文档而遍历的文档。NoteDocuments returned in the在as
field are not guaranteed to be in any order.as
字段中返回的文档不保证按任何顺序排列。maxDepth
Optional.可选的。Non-negative integral number specifying the maximum recursion depth.指定最大递归深度的非负整数。depthField
Optional.可选的。Name of the field to add to each traversed document in the search path.要添加到搜索路径中每个已遍历文档的字段的名称。The value of this field is the recursion depth for the document, represented as a此字段的值是文档的递归深度,表示为NumberLong
.NumberLong
。Recursion depth value starts at zero, so the first lookup corresponds to zero depth.递归深度值从零开始,因此第一次查找对应于零深度。restrictSearchWithMatch
Optional.可选的。A document specifying additional conditions for the recursive search.为递归搜索指定附加条件的文档。The syntax is identical to query filter syntax.语法与查询筛选器语法相同。NoteYou cannot use any aggregation expression in this filter.不能在此筛选器中使用任何聚合表达式。For example, a query document such as例如,查询文档:{ lastName: { $ne: "$lastName" } }
will not work in this context to find documents in which the将无法在此上下文中查找lastName
value is different from thelastName
value of the input document, because"$lastName"
will act as a string literal, not a field path.lastName
值与输入文档的lastName
值不同的文档,因为"$lastName"
将充当字符串文本,而不是字段路径。
Considerations注意事项
Sharded Collections分片集合
Starting in MongoDB 5.1, you can specify sharded collections in the 从MongoDB 5.1开始,您可以在from
parameter of $graphLookup
stages.$graphLookup
阶段的from
参数中指定分片集合。
Max Depth最大深度
Setting the 将maxDepth
field to 0
is equivalent to a non-recursive $graphLookup
search stage.maxDepth
字段设置为0
相当于非递归的$graphLookup
搜索阶段。
Memory内存
The $graphLookup
stage must stay within the 100 megabyte memory limit. $graphLookup
阶段必须保持在100兆字节内存限制内。If 如果为allowDiskUse: true
is specified for the aggregate()
operation, the $graphLookup
stage ignores the option. aggregate()
操作指定了allowDiskUse: true
,则$graphLookup
阶段将忽略该选项。If there are other stages in the 如果aggregate()
operation, allowDiskUse: true
option is in effect for these other stages.aggregate()
操作中还有其他阶段,则allowDiskUse:true
选项对这些其他阶段有效。
See aggregration pipeline limitations for more information.有关更多信息,请参阅聚合管道限制。
Views and Collation视图和排序
If performing an aggregation that involves multiple views, such as with 如果执行涉及多个视图的聚合,例如使用$lookup
or $graphLookup
, the views must have the same collation.$lookup
或$graphLookup
,则这些视图必须具有相同的排序规则。
Examples实例
Within a Single Collection在单个集合中
A collection named 名为employees
has the following documents: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" }
The following 以下$graphLookup
operation recursively matches on the reportsTo
and name
fields in the employees
collection, returning the reporting hierarchy for each person:$graphLookup
操作递归匹配employees
集合中的reportsTo
和name
字段,返回每个人的报告层次结构:
db.employees.aggregate( [
{
$graphLookup: {
from: "employees",
startWith: "$reportsTo",
connectFromField: "reportsTo",
connectToField: "name",
as: "reportingHierarchy"
}
}
] )
The operation returns the following:该操作返回以下内容:
{
"_id" : 1,
"name" : "Dev",
"reportingHierarchy" : [ ]
}
{
"_id" : 2,
"name" : "Eliot",
"reportsTo" : "Dev",
"reportingHierarchy" : [
{ "_id" : 1, "name" : "Dev" }
]
}
{
"_id" : 3,
"name" : "Ron",
"reportsTo" : "Eliot",
"reportingHierarchy" : [
{ "_id" : 1, "name" : "Dev" },
{ "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" }
]
}
{
"_id" : 4,
"name" : "Andrew",
"reportsTo" : "Eliot",
"reportingHierarchy" : [
{ "_id" : 1, "name" : "Dev" },
{ "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" }
]
}
{
"_id" : 5,
"name" : "Asya",
"reportsTo" : "Ron",
"reportingHierarchy" : [
{ "_id" : 1, "name" : "Dev" },
{ "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" },
{ "_id" : 3, "name" : "Ron", "reportsTo" : "Eliot" }
]
}
{
"_id" : 6,
"name" : "Dan",
"reportsTo" : "Andrew",
"reportingHierarchy" : [
{ "_id" : 1, "name" : "Dev" },
{ "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" },
{ "_id" : 4, "name" : "Andrew", "reportsTo" : "Eliot" }
]
}
The following table provides a traversal path for the document 下表提供了文档{ "_id" : 5, "name" : "Asya", "reportsTo" : "Ron" }
:{ "_id" : 5, "name" : "Asya", "reportsTo" : "Ron" }
的遍历路径:
Start value | reportsTo value of the document: reportsTo 值:{ ... "reportsTo" : "Ron" } |
---|---|
Depth 0 |
{ "_id" : 3, "name" : "Ron", "reportsTo" : "Eliot" } |
Depth 1 |
{ "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" } |
Depth 2 |
{ "_id" : 1, "name" : "Dev" } |
The output generates the hierarchy 输出生成层次结构Asya -> Ron -> Eliot -> Dev
.Asya -> Ron -> Eliot -> Dev
。
Across Multiple Collections跨多个集合
Like 与$lookup
, $graphLookup
can access another collection in the same database.$lookup
一样,$graphLookup
可以访问同一数据库中的另一个集合。
For example, create a database with two collections:例如,创建一个包含两个集合的数据库:
An包含以下文件的airports
collection with the following documents:airports
集合: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" ] }
] )Atravelers
collection with the following documents:travelers
集合包括以下文件:db.travelers.insertMany( [
{ "_id" : 1, "name" : "Dev", "nearestAirport" : "JFK" },
{ "_id" : 2, "name" : "Eliot", "nearestAirport" : "JFK" },
{ "_id" : 3, "name" : "Jeff", "nearestAirport" : "BOS" }
] )
For each document in the 对于travelers
collection, the following aggregation operation looks up the nearestAirport
value in the airports
collection and recursively matches the connects
field to the airport
field. travelers
集合中的每个文档,以下聚合操作在airports
集合中查找nearestAirport
值,并递归地将connects
字段与airport
字段匹配。The operation specifies a maximum recursion depth of 该操作指定最大递归深度为2
.2
。
db.travelers.aggregate( [
{
$graphLookup: {
from: "airports",
startWith: "$nearestAirport",
connectFromField: "connects",
connectToField: "airport",
maxDepth: 2,
depthField: "numConnections",
as: "destinations"
}
}
] )
The operation returns the following results:该操作返回以下结果:
{
"_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) }
]
}
The following table provides a traversal path for the recursive search, up to depth 下表提供了递归搜索的遍历路径,直到深度2
, where the starting airport
is JFK
:2
,其中起始airport
是JFK
:
Start value | nearestAirport value from the travelers collection: travelers 集合中nearestAirport 的值:{ ... "nearestAirport" : "JFK" } |
---|---|
Depth 0 |
{ "_id" : 0, "airport" : "JFK", "connects" : [ "BOS", "ORD" ] } |
Depth 1 |
{ "_id" : 1, "airport" : "BOS", "connects" : [ "JFK", "PWM" ] } |
Depth 2 |
{ "_id" : 3, "airport" : "PWM", "connects" : [ "BOS", "LHR" ] } |
With a Query Filter使用查询筛选器
The following example uses a collection with a set of documents containing names of people along with arrays of their friends and their hobbies. 下面的示例使用一个集合,其中包含一组文档,其中包含人名以及他们的朋友和爱好的数组。An aggregation operation finds one particular person and traverses her network of connections to find people who list 聚合操作找到一个特定的人,并遍历她的关系网络,找到将golf
among their hobbies.golf
列为自己爱好的人。
A collection named 名为people
contains the following documents:people
的集合包含以下文档:
{
"_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" ]
}
The following aggregation operation uses three stages:以下聚合操作使用三个阶段:
$match
matches on documents with aname
field containing the string"Tanya Jordan"
.$match
在具有包含字符串"Tanya Jordan"
的name
字段的文档中匹配。Returns one output document.返回一个输出文档。$graphLookup
connects the output document'sfriends
field with thename
field of other documents in the collection to traverseTanya Jordan's
network of connections.$graphLookup
将输出文档的friend
s字段与集合中其他文档的name
字段连接起来,以遍历Tanya Jordan
的连接网络。This stage uses the此阶段使用restrictSearchWithMatch
parameter to find only documents in which thehobbies
array containsgolf
.restrictSearchWithMatch
参数仅查找hobbies
数组中包含golf
的文档。Returns one output document.返回一个输出文档。$project
shapes the output document.对输出文档进行塑形。The names listed in在connections who play golf
are taken from thename
field of the documents listed in the input document'sgolfers
array.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"
}
}
] )
The operation returns the following document:该操作返回以下文档:
{
"_id" : 1,
"name" : "Tanya Jordan",
"friends" : [
"Shirley Soto",
"Terry Hawkins",
"Carole Hale"
],
"connections who play golf" : [
"Joseph Dennis",
"Tanya Jordan",
"Angelo Ward",
"Carole Hale"
]
}
Additional Resource额外的资源
Webinar: Working with Graph Data in MongoDB网络研讨会:在MongoDB中使用图形数据