已知起止节点如何编写Cypher查询获取两点间所有节点与关系
Cypher查询两点间路径及节点关系方案
一、基于现有APOC存储过程的实现
你当前使用的apoc.path.spanningTree返回的path对象可以通过Cypher内置函数直接提取节点和关系,无需额外处理:
- 提取单条路径的节点与关系
如果仅需获取任意一条起止节点间的路径,修改你的查询语句即可:
MATCH (start:temp {Name:"Joel"}), (end:temp {Name:"Jack"}) CALL apoc.path.spanningTree(start,{ terminatorNodes:[end], maxLevel: 10 // 按需设置最大遍历跳数,避免全库扫描 }) YIELD path RETURN nodes(path) AS 路径所有节点, relationships(path) AS 路径所有关系
如果需要展开为单行单节点/关系的格式,可搭配UNWIND使用:
MATCH (start:temp {Name:"Joel"}), (end:temp {Name:"Jack"}) CALL apoc.path.spanningTree(start,{terminatorNodes:[end], maxLevel:10}) YIELD path UNWIND nodes(path) AS node UNWIND relationships(path) AS rel RETURN collect(DISTINCT node) AS all_nodes, collect(DISTINCT rel) AS all_rels
- 获取两点间所有路径的节点与关系
如果需要返回两点间的所有简单路径,替换为apoc.path.allSimplePaths即可:
MATCH (start:temp {Name:"Joel"}), (end:temp {Name:"Jack"}) CALL apoc.path.allSimplePaths(start, end, { maxLevel:10 // 必须设置最大跳数限制,避免内存溢出 }) YIELD path RETURN nodes(path) AS path_nodes, relationships(path) AS path_rels
二、不依赖APOC的原生Cypher实现
原生Cypher支持无固定长度的双向变长路径查询,无需提前知晓路径长度和关系类型:
MATCH (start:temp {Name:"Joel"}), (end:temp {Name:"Jack"}) MATCH p = (start)-[*..10]-(end) // 不写箭头代表双向匹配,*..10代表最多10跳,按需调整 WHERE ALL(n IN nodes(p) WHERE size([x IN nodes(p) WHERE x = n]) = 1) // 过滤循环路径,仅保留节点不重复的简单路径 RETURN nodes(p) AS 路径所有节点, relationships(p) AS 路径所有关系
注意事项
- 数百万节点的大图场景下,必须设置合理的最大跳数限制,否则会出现遍历扩散导致内存溢出、查询超时
- 建议给
:temp(Name)建立唯一索引,加速起止节点的匹配效率 - 原生变长路径查询性能弱于APOC优化后的路径查询,大图长路径场景优先使用APOC方案
内容的提问来源于stack exchange,提问作者SOMESH NANDKISHOR PANDE
相关产品推荐
相关产品推荐

