不能保证在
as
字段中返回的文档以任何 Sequences 排列。
|
|
maxDepth
| *可选.*非负整数,指定最大递归深度。
|
depthField
| *可选.*要添加到搜索路径中每个已遍历文档的字段名称。该字段的值是文档的递归深度,表示为
NumberLong
。递归深度值从零开始,因此第一次查找对应于零深度。
|
restrictSearchWithMatch
| *可选.*为递归搜索指定其他条件的文档。语法与
query filter
语法相同。
> [!NOTE|label:Note]
您不能在此过滤器中使用任何
aggregation expression
。例如,查询文档如
{ lastName: { $ne: "$lastName" } }
在这种情况下将无法找到
lastName
值与 Importing 文档的
lastName
值不同的文档,因为
"$lastName"
将充当字符串 Literals,而不是字段路径。
|
from
中指定的集合不能为
sharded
。但是,可以对运行
aggregate()
方法的集合进行分片。也就是说,在下面:
db.collection.aggregate([
{ $graphLookup: { from: "fromCollection", ... } }
collection
可以被分片。
fromCollection
无法分片。
要加入多个分片集合,请考虑:
修改 Client 端应用程序以执行手动查找,而不是使用$graphLookup聚合阶段。
如果可能,请使用嵌入式数据模型消除加入集合的需要。
将maxDepth
字段设置为0
等效于非递归$graphLookup搜索阶段。
$graphLookup阶段必须保持在 100 MiB 内存限制内。如果为aggregate()操作指定了allowDiskUse: true
,则$graphLookup阶段将忽略该选项。如果在aggregate()操作中还有其他观察allowDiskUse: true
的阶段,则allowDiskUse: true
选项对这些其他阶段有效。
有关更多信息,请参见聚集管线限制。
如果执行涉及多个视图的聚合(例如$lookup或$graphLookup),则这些视图必须具有相同的collation。
名为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" }
以下$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" : 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" }
下表提供了文档{ "_id" : 5, "name" : "Asya", "reportsTo" : "Ron" }
的遍历路径:
起始值文档的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" }
输出生成层次结构Asya -> Ron -> Eliot -> Dev
。
像$lookup一样,$graphLookup可以访问同一数据库中的另一个集合。
在以下示例中,数据库包含两个集合:
具有以下文档的集合airports
:
{ "_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
:
{ "_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
:
起始值来自travelers
集合的nearestAirport
值:
{ ... "nearestAirport" : "JFK" }
Depth 0{ "_id" : 0, "airport" : "JFK", "connects" : [ "BOS", "ORD" ] }
Depth 1{ "_id" : 1, "airport" : "BOS", "connects" : [ "JFK", "PWM"] }
{ "_id" : 2, "airport" : "ORD", "connects" : [ "JFK"] }
Depth 2{ "_id" : 3, "airport" : "PWM", "connects" : [ "BOS", "LHR" ] }
下面的示例使用一个集合,该集合包含一组文档,其中包含人的名字以及他们的朋友和爱好的数组。聚集操作找到一个特定的人,并遍历她的联系网络,以找到在他们的兴趣中列出golf
的人。
名为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" ]
以下聚合操作分为三个阶段:
$match与包含字符串"Tanya Jordan"
的name
字段的文档匹配。返回一个输出文档。
$graphLookup将输出文档的friends
字段与集合中其他文档的name
字段连接,以遍历Tanya Jordan's
连接网络。此阶段使用restrictSearchWithMatch
参数仅查找hobbies
数组包含golf
的文档。返回一个输出文档。
$project对输出文档进行整形。 connections who play golf
中列出的名称取自 Importing 文档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 中使用图数据