如何修改Cypher查询使Neo4j 3.5中虚拟关系遍历返回结果?
问题分析与解决方案
核心原因
你修改后的语句MATCH p = (a)<-[inv:teninvmerge*1..5]-(end)无结果,是因为:
a是虚拟节点,仅存在于当前查询的执行上下文,数据库中没有任何真实节点通过teninvmerge关系指向它;- 普通
MATCH语句只能匹配数据库中持久化的真实关系,无法识别虚拟关系作为路径的起始连接。
而你原来的语句能返回结果,是因为它通过虚拟关系关联到了真实的first节点,再从first遍历数据库中的真实关系,形成了完整的有效路径。
解决方案
要实现从虚拟节点a出发的遍历查询,需要将虚拟节点+虚拟关系的片段,与真实节点的遍历路径拼接起来,以下是两种可行的写法:
写法一:使用APOC路径工具拼接路径
WITH ['aab40c4d65d5c0a428ed84dc0109b0c4', '000415fee2b0272cdcc2439f521b2e2e'] AS param CALL apoc.create.vNode(['ent'], {nodeid: 'test'}) YIELD node AS a MATCH (first:ent) WHERE first.nodeid IN param CALL apoc.create.vRelationship(first, 'teninvmerge', {conprop: "0.5"}, a) YIELD rel AS b // 从真实节点first出发,反向遍历1-5步teninvmerge关系 CALL apoc.path.expand(first, '<teninvmerge>', '', 1, 5) YIELD path AS realPath // 将虚拟关系片段与真实路径拼接,得到完整结果路径 RETURN apoc.path.combine(b, realPath) AS p
写法二:手动拼接路径片段
WITH ['aab40c4d65d5c0a428ed84dc0109b0c4', '000415fee2b0272cdcc2439f521b2e2e'] AS param CALL apoc.create.vNode(['ent'], {nodeid: 'test'}) YIELD node AS a MATCH (first:ent) WHERE first.nodeid IN param CALL apoc.create.vRelationship(first, 'teninvmerge', {conprop: "0.5"}, a) YIELD rel AS b // 匹配真实节点的遍历路径 MATCH realPath = (first)<-[inv:teninvmerge*1..5]-(end) // 将虚拟节点+虚拟关系的片段与真实路径拼接 RETURN (a)-[b]->(first) + realPath AS p
原理说明
两种写法的核心逻辑一致:
- 先创建虚拟节点和虚拟关系,关联到真实的
first节点; - 单独遍历
first节点对应的真实路径; - 将虚拟片段与真实路径拼接,形成从虚拟节点
a出发的完整路径。
内容的提问来源于stack exchange,提问作者ning wu
相关产品推荐
相关产品推荐

