扩展到子图
扩展到子图过程会将从起始 NODE
可达的子图 NODE
值扩展到最大级别,遵循 RELATIONSHIP
值并遵守标签过滤器。返回子图中 NODE
值的集合,以及所有子图 NODE
值之间的 RELATIONSHIP
值的集合。它允许对扩展这些子图的遍历进行细粒度控制。
过程概述
该过程描述如下
限定名称 | 类型 |
---|---|
apoc.path.subgraphAll |
|
配置参数
该过程支持以下配置参数
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
minLevel |
INTEGER |
-1 |
遍历中的最小跳数。如果指定,必须为 0 或 1 |
maxLevel |
INTEGER |
-1 |
遍历中的最大跳数 |
relationshipFilter |
STRING |
null |
要遍历的关系类型和方向。 参见 关系过滤器。 |
labelFilter |
STRING |
null |
要遍历的节点标签。 参见 标签过滤器。 |
beginSequenceAtStart |
BOOLEAN |
true |
从起始节点的一个节点开始匹配节点标签和/或关系类型序列(在 |
bfs |
BOOLEAN |
true |
遍历时使用广度优先搜索。如果设置为 |
filterStartNode |
BOOLEAN |
false |
|
limit |
INTEGER |
-1 |
限制返回的路径数量。当使用 |
endNodes |
LIST<NODE> |
null |
只有这些节点可以结束返回的路径,如果可能,扩展将继续越过这些节点。 |
terminatorNodes |
LIST<NODE> |
null |
只有这些节点可以结束返回的路径,并且扩展不会越过这些节点继续。 |
allowlistNodes |
LIST<NODE> |
null |
只有这些节点允许在扩展中(如果存在,endNodes 和 terminatorNodes 也将被允许)。 |
denylistNodes |
LIST<NODE> |
null |
返回的路径都不会包含这些节点。 |
whitelistNodes (已废弃) |
LIST<NODE> |
null |
参见 allowlistNodes。 |
blacklistNodes (已废弃) |
LIST<NODE> |
null |
参见 denylistNodes。 |
它还包含以下固定参数
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
uniqueness |
STRING |
NODE_GLOBAL |
遍历中扩展关系时使用的策略。 |
关系过滤器
关系过滤器的语法描述如下
语法: [<]RELATIONSHIP_TYPE1[>]|[<]RELATIONSHIP_TYPE2[>]|…
输入 | 类型 | 方向 |
---|---|---|
|
|
出站 |
|
|
入站 |
|
|
双向 |
|
|
出站 |
|
|
入站 |
标签过滤器
标签过滤器的语法描述如下
语法: [+-/>]LABEL1|LABEL2|*|…
符号 | 过滤器类型 | 输入示例 | 描述 |
---|---|---|---|
|
黑名单 |
|
路径中没有节点会包含黑名单中的标签。 |
|
白名单 |
|
路径中的所有节点必须具有白名单中的标签(如果使用终止节点和结束节点过滤器,则豁免)。如果没有白名单运算符,则允许所有标签。 |
|
终止 |
|
仅返回到达具有给定标签的节点的路径,并停止在其之外的进一步扩展。终止节点不必遵守白名单。终止过滤优先于结束节点过滤。 |
|
结束节点 |
|
仅返回到达具有给定标签的节点的路径,但继续扩展以匹配其之外的结束节点。结束节点不必遵守白名单即可返回,但只有当节点具有白名单中的标签时才允许在其之外进行扩展。 |
|
复合标签 |
|
这返回标签的合取,例如 /Foo:Bar 意味着终止节点必须同时匹配 |
标签过滤器运算符的优先级和行为
可以同时使用多个标签过滤器运算符。以下面为例
labelFilter:'+Person|Movie|-SciFi|>Western|/Romance'
如果解析此标签过滤器,我们可以看到
-
:Person
和:Movie
标签在白名单中 -
:SciFi
在黑名单中 -
:Western
是一个结束节点标签 -
:Romance
是一个终止标签。
运算符评估的优先级不取决于其在 labelFilter 中的位置,而是固定的
黑名单过滤器 -
,终止过滤器 /
,结束节点过滤器 >
,白名单过滤器 +
。
这意味着
-
返回路径的节点中绝不会出现黑名单标签
-
,即使相同的标签(或具有黑名单标签的另一个节点的标签)包含在其他过滤器列表中。 -
如果使用终止过滤器
/
或结束节点过滤器>
,则仅返回到达带有这些标签的节点的路径作为结果。这些结束节点不受白名单过滤器的限制。 -
如果一个节点是终止节点
/
,则不会发生超出该节点的进一步扩展。 -
白名单仅适用于到达终止或结束节点过滤器中的结束节点(但不包括这些节点)之前的节点。如果没有结束节点或终止节点运算符,则白名单适用于路径中的所有节点。
-
如果 labelFilter 中没有白名单运算符,则视为所有标签都在白名单中。
示例
本节中的示例基于以下示例图
MERGE (mark:Person:DevRel {name: "Mark"})
MERGE (lju:Person:DevRel {name: "Lju"})
MERGE (praveena:Person:Engineering {name: "Praveena"})
MERGE (zhen:Person:Engineering {name: "Zhen"})
MERGE (martin:Person:Engineering {name: "Martin"})
MERGE (joe:Person:Field {name: "Joe"})
MERGE (stefan:Person:Field {name: "Stefan"})
MERGE (alicia:Person:Product {name: "Alicia"})
MERGE (jake:Person:Product {name: "Jake"})
MERGE (john:Person:Product {name: "John"})
MERGE (jonny:Person:Sales {name: "Jonny"})
MERGE (anthony:Person:Sales {name: "Anthony"})
MERGE (rik:Person:Sales {name: "Rik"})
MERGE (zhen)-[:KNOWS]-(stefan)
MERGE (zhen)-[:KNOWS]-(lju)
MERGE (zhen)-[:KNOWS]-(praveena)
MERGE (zhen)-[:KNOWS]-(martin)
MERGE (mark)-[:KNOWS]-(jake)
MERGE (alicia)-[:KNOWS]-(jake)
MERGE (jonny)-[:KNOWS]-(anthony)
MERGE (john)-[:KNOWS]-(rik)
MERGE (alicia)-[:FOLLOWS]->(joe)
MERGE (joe)-[:FOLLOWS]->(mark)
MERGE (joe)-[:FOLLOWS]->(praveena)
MERGE (joe)-[:FOLLOWS]->(zhen)
MERGE (mark)-[:FOLLOWS]->(stefan)
MERGE (stefan)-[:FOLLOWS]->(joe)
MERGE (praveena)-[:FOLLOWS]->(joe)
MERGE (lju)-[:FOLLOWS]->(jake)
MERGE (alicia)-[:FOLLOWS]->(jonny)
MERGE (zhen)-[:FOLLOWS]->(john)
MERGE (anthony)-[:FOLLOWS]->(joe)
下面的 Neo4j Browser 可视化显示了示例图
KNOWS
关系类型被认为是双向的,如果 Zhen 认识 Stefan,我们可以推断 Stefan 认识 Zhen。当使用 KNOWS
关系时,我们将忽略方向。
FOLLOWS
关系有方向,因此在使用它时我们会指定方向。
关系类型和节点标签过滤器
让我们从 Praveena 节点开始扩展路径。我们只想考虑 KNOWS
关系类型,因此我们将其指定为 relationshipFilter
参数。
KNOWS
关系可达的子图MATCH (p:Person {name: "Praveena"})
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "KNOWS",
minLevel: 1,
maxLevel: 2
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Praveena 的子图 中看到返回子图的 Neo4j Browser 可视化。
我们还可以提供节点标签过滤器来限制返回的节点。如果只想返回路径中每个节点都具有 Engineering
标签的路径,我们将为 labelFilter
参数提供值 +Engineering
。
KNOWS
关系可达的 Engineering
人员子图MATCH (p:Person {name: "Praveena"})
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "KNOWS",
labelFilter: "+Engineering",
minLevel: 1,
maxLevel: 2
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Praveena 的 Engineering
节点子图 中看到返回子图的 Neo4j Browser 可视化。
Engineering
节点子图我们失去了 Lju 和 Stefan,因为这些节点没有 Engineering
标签。
我们可以指定多种关系类型。以下查询从 Alicia 节点开始,然后扩展 FOLLOWS
和 KNOWS
关系
FOLLOWS
或 KNOWS
关系可达的人员子图MATCH (p:Person {name: "Alicia"})
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
minLevel: 1,
maxLevel: 3
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Alicia 的子图 中看到返回子图的 Neo4j Browser 可视化。
这个子图包含了我们图中除一个人之外的所有人,这意味着 Alicia 的连接非常广泛。
我们还可以使用标签过滤器指定遍历终止条件。如果我们希望遍历在遇到包含 Engineering
标签的节点时立即终止,可以使用 /Engineering
节点过滤器。
FOLLOWS
或 KNOWS
关系可达的子图,在到达具有 Engineering
标签的节点时立即终止MATCH (p:Person {name: "Alicia"})
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
labelFilter: "/Engineering",
minLevel: 1,
maxLevel: 3
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Alicia 的子图在 Engineering
节点处终止 中看到返回子图的 Neo4j Browser 可视化。
Engineering
节点处终止我们现在只剩下 Zhen 和 Praveena 两个人。但是这个查询没有捕获所有从 Alicia 开始,并以 Engineering
标签节点结束的路径。我们可以使用 >Engineering
节点过滤器来定义一个遍历,它将
-
仅返回以
Engineering
标签节点终止的路径 -
在此之后继续扩展到结束节点,寻找更多以
Engineering
标签结束的路径
FOLLOWS
或 KNOWS
关系可达的 Engineering
人员子图MATCH (p:Person {name: "Alicia"})
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
labelFilter: ">Engineering",
minLevel: 1,
maxLevel: 3
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Alicia 的子图在 Engineering
节点处结束 中看到返回子图的 Neo4j Browser 可视化。
Engineering
节点处结束我们的子图现在还包括 Martin,他通过 Zhen 的关系到达。
终止节点和结束节点
除了为遍历指定终止标签和结束标签外,我们还可以指定终止节点和结束节点。
让我们在之前的查询基础上进行构建,该查询找到了 Alicia KNOWS
或 FOLLOWS
的人。我们希望返回的子图在到达 Mark、Joe、Zhen 或 Praveena 节点时立即停止。我们可以通过将这些节点传递给 terminatorNodes
参数来实现。
FOLLOWS
或 KNOWS
关系可达的人员子图,在到达 Mark、Joe、Zhen 或 Rik 节点时立即终止MATCH (p:Person {name: "Alicia"})
MATCH (terminator:Person)
WHERE terminator.name IN ["Mark", "Joe", "Zhen", "Rik"]
WITH p, collect(terminator) AS terminatorNodes
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
minLevel: 1,
maxLevel: 3,
terminatorNodes: terminatorNodes
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Alicia 的子图在 Mark、Joe、Zhen 或 Rik 处终止 中看到返回子图的 Neo4j Browser 可视化。
我们有到达 Mark 和 Joe 的路径,但 Zhen 和 Rik 无法到达。这可能是因为没有不经过 Mark 和 Joe 的路径可以到达 Zhen 和 Rik,也可能意味着基于其他遍历条件没有路径。
我们可以通过将这些节点传递给 endNodes
参数来查找 Mark、Joe、Zhen 或 Rik 是否可达。
FOLLOWS
或 KNOWS
关系可达的人员子图,在到达 Mark、Joe、Zhen 或 Rik 节点时立即结束MATCH (p:Person {name: "Alicia"})
MATCH (end:Person)
WHERE end.name IN ["Mark", "Joe", "Zhen", "Rik"]
WITH p, collect(end) AS endNodes
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
minLevel: 1,
maxLevel: 3,
endNodes: endNodes
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Alicia 的子图在 Mark、Joe、Zhen 或 Rik 处结束 中看到返回子图的 Neo4j Browser 可视化。
我们现在可以到达 Joe、Mark 和 Zhen,但 Rik 仍然无法到达。
白名单节点和黑名单节点
也可以指定白名单节点和黑名单节点。
让我们在之前的查询基础上进行构建,该查询找到了 Alicia KNOWS
或 FOLLOWS
的人。我们希望任何返回的路径只包含 Mark、Joe、Zhen 和 Praveena 节点,这可以通过将这些节点传递给 allowlistNodes
参数来实现。
FOLLOWS
或 KNOWS
关系类型可达的节点,其中到达这些节点的路径必须只包含 Mark、Jonny 或 ZhenMATCH (p:Person {name: "Alicia"})
MATCH (allowlist:Person)
WHERE allowlist.name IN ["Jonny", "Mark", "Zhen"]
WITH p, collect(allowlist) AS allowlistNodes
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
minLevel: 1,
maxLevel: 3,
allowlistNodes: allowlistNodes
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Alicia 的子图,其中到达节点的路径包含 Mark、Jonny 或 Zhen 中看到返回子图的 Neo4j Browser 可视化。
只有 Jonny 可以到达。因此我们可以推断 Mark 和 Zhen 只能通过不在白名单中的另一个节点到达。
黑名单用于从通往可达节点的路径中排除节点。如果我们想返回不经过 Joe 即可到达的节点,可以通过将 Joe 节点传递给 denylistNodes
参数来实现。
FOLLOWS
或 KNOWS
关系类型可达的节点,其中到达这些节点的路径不经过 JoeMATCH (p:Person {name: "Alicia"})
MATCH (joe:Person {name: "Joe"})
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
minLevel: 1,
maxLevel: 3,
denylistNodes: [joe]
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Alicia 的子图,其中到达节点的路径不能经过 Joe 中看到返回子图的 Neo4j Browser 可视化。
关系类型序列
关系类型序列可以通过逗号分隔传递给 relationshipFilter
的值来指定。
例如,如果我们想从 Joe 节点开始,并遍历出站方向的 FOLLOWS
关系和任意方向的 KNOWS
关系序列,我们可以指定关系过滤器 FOLLOWS>,KNOWS
。
FOLLOWS
和 KNOWS
关系类型可达的节点MATCH (p:Person {name: "Joe"})
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>,KNOWS",
beginSequenceAtStart: true,
minLevel: 1,
maxLevel: 4
})
YIELD nodes, relationships
RETURN nodes, relationships;
我们可以在 从 Joe 的子图通过交替 FOLLOWS
和 KNOWS
关系类型 中看到返回子图的 Neo4j Browser 可视化。
FOLLOWS
和 KNOWS
关系类型