|| apoc.path.expand - APOC 核心文档 - Neo4j 文档

apoc.path.expand

此过程不被认为是多线程安全运行的。因此,并行运行时不支持此过程。欲了解更多信息,请参阅Cypher 手册 → 并行运行时

详情

语法

apoc.path.expand(startNode, relFilter, labelFilter, minDepth, maxDepth) :: (path)

描述

返回从起始节点扩展的路径值,这些路径遵循给定关系类型,深度范围从最小深度到最大深度。

输入参数

名称

类型

描述

startNode

ANY

算法的起始节点。startNode 可以是 STRING (elementId())、INTEGER (id())、NODELIST<STRING | INTEGER | NODE> 类型。

relFilter

STRING

返回关系上允许的类型白名单。

labelFilter

STRING

返回节点上允许的标签白名单。

minDepth

INTEGER

返回路径中允许的最小跳数。

maxDepth

INTEGER

返回路径中允许的最大跳数。

返回参数

名称

类型

描述

path

PATH

扩展的路径。

使用示例

本节中的示例基于以下示例图。

MERGE (mark:Person:DevRel {name: "Mark"})
MERGE (praveena:Person:Engineering {name: "Praveena"})
MERGE (joe:Person:Field {name: "Joe"})
MERGE (lju:Person:DevRel {name: "Lju"})
MERGE (zhen:Person:Engineering {name: "Zhen"})
MERGE (stefan:Person:Field {name: "Stefan"})
MERGE (alicia:Person:Product {name: "Alicia"})
MERGE (martin:Person:Engineering {name: "Martin"})
MERGE (jake:Person:Product {name: "Jake"})

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 (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)

下方 Neo4j Browser 可视化显示了示例图。

apoc.path.expand

KNOWS 关系类型被认为是双向的,即如果 Zhen 认识 Stefan,我们可以推断 Stefan 认识 Zhen。当使用 KNOWS 关系时,我们将忽略方向。

FOLLOWS 关系有方向,因此在使用它时我们将指定方向。

让我们从 Praveena 节点开始扩展路径。我们只希望考虑 KNOWS 关系类型,因此我们将其指定为关系过滤器。

以下返回 Praveena 认识的人的路径,跳数为 1 到 2。
MATCH (p:Person {name: "Praveena"})
CALL apoc.path.expand(p, "KNOWS", null, 1, 2)
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops;
结果
path 跳数

(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})

1

(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Engineering {name: "Martin"})

2

(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:DevRel {name: "Lju"})

2

(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Field {name: "Stefan"})

2

Praveena 只与 Zhen 有直接的 KNOWS 关系,但 Zhen 与另外 3 个人有 KNOWS 关系,这意味着他们与 Praveena 的距离是 2 跳。

我们还可以提供一个节点标签过滤器来限制返回的节点。以下查询仅返回每个节点都具有 Engineering 标签的路径。

以下返回包含 Praveena 认识的仅具有 Engineering 标签的人的路径,跳数为 1 到 2。
MATCH (p:Person {name: "Praveena"})
CALL apoc.path.expand(p, "KNOWS", "+Engineering", 1, 2)
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops;
结果
path 跳数

(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})

1

(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Engineering {name: "Martin"})

2

我们失去了以 Lju 和 Stefan 结尾的路径,因为这两个节点都没有 Engineering 标签。

我们可以指定多种关系类型。以下查询从 Alicia 节点开始,然后扩展 FOLLOWSKNOWS 关系。

以下返回包含 Alicia 关注认识的人的路径,跳数为 1 到 3。
MATCH (p:Person {name: "Alicia"})
CALL apoc.path.expand(p, "FOLLOWS>|KNOWS", "", 1, 3)
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops;
结果
path 跳数

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})

1

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Sales {name: "Jonny"})

1

(:Person:Product {name: "Alicia"})-[:KNOWS]→(:Person:Product {name: "Jake"})

1

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})

2

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Praveena"})

2

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:DevRel {name: "Mark"})

2

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Sales {name: "Jonny"})-[:KNOWS]→(:Person:Sales {name: "Anthony"})

2

(:Person:Product {name: "Alicia"})-[:KNOWS]→(:Person:Product {name: "Jake"})←[:KNOWS]-(:Person:DevRel {name: "Mark"})

2

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})-[:FOLLOWS]→(:Person:Product {name: "John"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Engineering {name: "Martin"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Engineering {name: "Praveena"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:DevRel {name: "Lju"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Field {name: "Stefan"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Praveena"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:DevRel {name: "Mark"})-[:FOLLOWS]→(:Person:Field {name: "Stefan"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:DevRel {name: "Mark"})-[:KNOWS]→(:Person:Product {name: "Jake"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Sales {name: "Jonny"})-[:KNOWS]→(:Person:Sales {name: "Anthony"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})

3

(:Person:Product {name: "Alicia"})-[:KNOWS]→(:Person:Product {name: "Jake"})←[:KNOWS]-(:Person:DevRel {name: "Mark"})-[:FOLLOWS]→(:Person:Field {name: "Stefan"})

3

此查询返回 19 条路径,Alicia 的连接非常广!

我们还可以使用标签过滤器指定遍历终止条件。如果希望遍历在遇到包含 Engineering 标签的节点时立即终止,可以使用 /Engineering 节点过滤器。

以下返回包含 Alicia 关注认识的人的路径,跳数为 1 到 3,在遇到具有 Engineering 标签的节点时立即终止。
MATCH (p:Person {name: "Alicia"})
CALL apoc.path.expand(p, "FOLLOWS>|KNOWS", "/Engineering", 1, 3)
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops;
结果
path 跳数

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})

2

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Praveena"})

2

现在只剩下两条路径。但此查询并未捕获所有从 Alicia 开始并以带有 Engineering 标签的节点结束的路径。我们可以使用 >Engineering 节点过滤器来定义一个遍历,该遍历将:

  • 只返回在具有 Engineering 标签的节点处终止的路径

  • 在此之后继续扩展到末端节点,寻找更多以 Engineering 标签结尾的路径

以下返回包含 Alicia 关注认识的人的路径,跳数为 1 到 3,其中路径以具有 Engineering 标签的节点结束。
MATCH (p:Person {name: "Alicia"})
CALL apoc.path.expand(p, "FOLLOWS>|KNOWS", ">Engineering", 1, 3)
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops;
结果
path 跳数

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})

2

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Praveena"})

2

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Engineering {name: "Martin"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Zhen"})-[:KNOWS]→(:Person:Engineering {name: "Praveena"})

3

(:Person:Product {name: "Alicia"})-[:FOLLOWS]→(:Person:Field {name: "Joe"})-[:FOLLOWS]→(:Person:Engineering {name: "Praveena"})←[:KNOWS]-(:Person:Engineering {name: "Zhen"})

3

我们的查询现在还返回经过 Praveena 和 Zhen 的路径,一条通往 Martin,还有一些回到 Zhen 和 Praveena 的路径!

© . This site is unofficial and not affiliated with Neo4j, Inc.