我很难找到一个干净,高效的Cypher查询,它可以让我识别从起始节点发出的所有不同路径,这样当存在多种关系类型时,路径中的每个关系都是相同的类型。
以下是该模型的简单版本:
CREATE (a), (b), (c), (d), (e), (f), (g),
(a)-[:X]->(b)-[:X]->(c)-[:X]->(d)-[:X]->(e),
(a)-[:Y]->(c)-[:Y]->(f)-[:Y]->(g)
在此模型中,(a)
有两种传出关系类型,X
和Y
。我想检索沿关系X
链接节点的所有路径以及沿关系Y
链接节点的所有路径。
我可以通过编写一系列查询,在cypher之外以编程方式执行此操作 从起始节点检索传出关系列表,然后检索每个关系的单个查询(作为批处理一起提交)。看起来像是:
START n=node(1)
MATCH n-[r]->()
RETURN COLLECT(DISTINCT TYPE(r)) as rels;
接下来是:
START n=node(1)
MATCH n-[:`reltype_param`*]->()
RETURN p as path;
以上内容满足了我的需求,但至少需要2次往返服务器(再次假设我在一次交易中将第二组查询一起批处理)。
单一查询方法有效,但效率极低,是以下单个Cypher查询:
START n=node(1)
MATCH p = n-[r*]->() WHERE
ALL (x in RELATIONSHIPS(p) WHERE TYPE(x) = TYPE(HEAD(RELATIONSHIPS(p))))
RETURN p as path;
该查询使用ALL
谓词来过滤沿路径的关系,强制路径中的每个关系与路径中的第一个关系匹配。然而,这实际上只是对所有可能路径的组合爆炸的过滤操作 - 比首先遍历已知的给定类型的关系效率低得多。
我觉得这应该可以通过一个Cypher查询来实现,但我无法做到这一点。
答案 0 :(得分:2)
这是一个小优化,至少不匹配路径会快速失败:
MATCH n-[r]->()
WITH distinct type(r) AS t
MATCH p = n-[r*]->()
WHERE type(r[-1]) = t // last entry matches
RETURN p AS path
如果你希望它能够真正发挥作用,那么这可能就是Java API中的一个。