路径操作

本节中的函数可用于创建、组合和拆分路径。

函数概览

可用函数如下所述

限定名称 类型

apoc.path.create
apoc.path.create(startNode NODE, rels LIST<RELATIONSHIP>) - 从给定的起始 NODELIST<RELATIONSHIP> 返回一个 PATH

函数

apoc.path.combine
apoc.path.combine(path1 PATH, path2 PATH) - 将两个给定的 PATH 值组合成一个 PATH

函数

apoc.path.slice
apoc.path.slice(path PATH, offset INTEGER, length INTEGER) - 返回从给定 PATH 的指定偏移量处截取指定长度的新 PATH

函数

apoc.path.elements
apoc.path.elements(path PATH) - 将给定 PATH 转换为 LIST<NODE \| RELATIONSHIP>

函数

示例

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

MERGE (manUtd:Club {name: 'Man Utd'})
MERGE (juventus:Club {name: 'Juventus'})
MERGE (flamengo:Club {name: 'Flamengo'})

MERGE (premierLeague:League {name: 'Premier League'})
MERGE (serieA:League {name: 'Serie A'})
MERGE (brasileirao:League {name: 'Brasileirão'})

MERGE (england:Country {name: 'England'})
MERGE (brazil:Country {name: 'Brazil'})

MERGE (uefa:Confederation {name: 'UEFA'})

MERGE (manUtd)-[:IN_LEAGUE]->(premierLeague)
MERGE (premierLeague)-[:IN_COUNTRY]->(england)
MERGE (england)-[:IN_CONFEDERATION]->(uefa)

MERGE (juventus)-[:IN_LEAGUE]->(serieA)

MERGE (flamengo)-[:IN_LEAGUE]->(brasileirao)
MERGE (brasileirao)-[:IN_COUNTRY]->(brazil);

apoc.path.create 函数从起始节点和关系列表创建路径。此函数的一个用例是组合来自 OPTIONAL MATCH 子句的关系。

以下查询从 OPTIONAL MATCH 子句返回的关系创建路径
MATCH (club:Club)
OPTIONAL MATCH (club)-[inLeague:IN_LEAGUE]->(league)
OPTIONAL MATCH (league)-[inCountry:IN_COUNTRY]->(country)
OPTIONAL MATCH (country)-[inConfederation:IN_CONFEDERATION]->(confederation)
RETURN club.name, apoc.path.create(club, [inLeague, inCountry, inConfederation]) AS path
ORDER BY length(path);
表 1. 结果
club.name path

"Juventus"

(:Club {name: "Juventus"})-[:IN_LEAGUE]→(:League {name: "Serie A"})

"Flamengo"

(:Club {name: "Flamengo"})-[:IN_LEAGUE]→(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

"Man Utd"

(:Club {name: "Man Utd"})-[:IN_LEAGUE]→(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})-[:IN_CONFEDERATION]→(:Confederation {name: "UEFA"})

如果我们要从包含两个 OPTIONAL MATCH 子句的查询创建路径,我们可以改用 apoc.path.combine 函数。

以下返回组合了 (club)-[:IN_LEAGUE]→(league)(league)-[:IN_COUNTRY]→(country) 路径的路径
MATCH (club:Club)
OPTIONAL MATCH path1 = (club)-[:IN_LEAGUE]->(league)
OPTIONAL MATCH path2 = (league)-[:IN_COUNTRY]->(country)
RETURN club.name, apoc.path.combine(path1, path2) AS path
ORDER BY length(path);
表 2. 结果
club.name path

"Juventus"

(:Club {name: "Juventus"})-[:IN_LEAGUE]→(:League {name: "Serie A"})

"Man Utd"

(:Club {name: "Man Utd"})-[:IN_LEAGUE]→(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})

"Flamengo"

(:Club {name: "Flamengo"})-[:IN_LEAGUE]→(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

apoc.path.slice 函数返回路径的子集,从指定的偏移量开始,长度为指定的元素数量。

以下返回组合路径的子集,从偏移量 1 开始,长度为 1
MATCH (club:Club)
OPTIONAL MATCH path1 = (club)-[:IN_LEAGUE]->(league)
OPTIONAL MATCH path2 = (league)-[:IN_COUNTRY]->(country)
WITH apoc.path.combine(path1, path2) AS path
RETURN apoc.path.slice(path, 1, 1);
表 3. 结果
apoc.path.slice(path, 1, 1)

(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})

(:League {name: "Serie A"})

(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

apoc.path.elements 函数将路径转换为节点和关系的列表。

以下返回 (club)-[:IN_LEAGUE]→(league)-[:IN_COUNTRY]→(country) 路径中的实体列表
MATCH path = (club:Club)-[:IN_LEAGUE]->(league)-[:IN_COUNTRY]->(country)
RETURN path, apoc.path.elements(path);
表 4. 结果
path apoc.path.elements(path)

(:Club {name: "Man Utd"})-[:IN_LEAGUE]→(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})

[(:Club {name: "Man Utd"}), [:IN_LEAGUE], (:League {name: "Premier League"}), [:IN_COUNTRY], (:Country {name: "England"})]

(:Club {name: "Flamengo"})-[:IN_LEAGUE]→(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

[(:Club {name: "Flamengo"}), [:IN_LEAGUE], (:League {name: "Brasileirão"}), [:IN_COUNTRY], (:Country {name: "Brazil"})]

我们可以使用此函数返回表示路径中包含的节点和关系的三元组流。

以下返回 (主语、谓语、宾语) 三元组
MATCH path = (club:Club)
OPTIONAL MATCH path1 = (club)-[:IN_LEAGUE]->(league)
OPTIONAL MATCH path2 = (league)-[:IN_COUNTRY]->(country)
WITH apoc.path.combine(path1, path2) AS path
WITH apoc.path.elements(path) AS elements
UNWIND range(0, size(elements)-2) AS index
WITH elements, index
WHERE index %2 = 0
RETURN elements[index] AS subject, elements[index+1] AS predicate, elements[index+2] AS object;
表 5. 结果
主语 谓语 宾语

(:Club {name: "Man Utd"})

[:IN_LEAGUE]

(:League {name: "Premier League"})

(:League {name: "Premier League"})

[:IN_COUNTRY]

(:Country {name: "England"})

(:Club {name: "Juventus"})

[:IN_LEAGUE]

(:League {name: "Serie A"})

(:Club {name: "Flamengo"})

[:IN_LEAGUE]

(:League {name: "Brasileirão"})

(:League {name: "Brasileirão"})

[:IN_COUNTRY]

(:Country {name: "Brazil"})