Neo4j - 通过节点的最短路径

Neo4j - shortestPath through node

我正在尝试通过具有标签 SomeImportantLabel 的特定节点 (b) 获取节点 (a) 和节点 (c) 之间的最短路径。画好了,这就是我想要的:

(a)-(?..)-(b:SomeImportantLabel)-(?..)-(c)

请注意 (?..) 表示中间可能有 'n' 个节点。

我正在寻找这样的交易:

match p = allShortestPaths((a)-[*]-(b:SomeImportantLabel)-[*]-(c)) 
where id(a) = 123 and id(c) = 456 
return nodes(p) as nodes, relationships(p) as rels;

由于在 shortestPath/allShortestPaths 函数中不可能有多个关系,我在 SO 上读到过你必须这样做:

match p1 = allShortestPaths((a)-[*]-(b:SomeImportantLabel)), p2=allShortestPaths((b:SomeImportantLabel)-[*]-(b)) 
where id(a) = 123 and id(c) = 456 
return nodes(p1)+nodes(p2) as nodes, relationships(p1)+relationships(p2) as rels;

然而,这给了我太多甚至没有涉及的节点,并且处理这个查询需要很长时间。我认为这是因为我不确定 2 个 allShortestPaths 函数中是否使用了相同的 (b) 节点。 或多或少会是这样的结果:

       /-(v2)
      /-(v1)
(a)-(x1)-(b)-(x2)-(c)
 \-(y1)   \-(z1)-(z2)

理想的解决方案是这样的:

(a)-(x1)-(b1)-(x2)-(c)
 \-(b2)-(y1)-(y2)-(c)

这意味着在 (a)(c) 之间找到了 2 条最短路径,它们经过节点 (b) 并带有标签 'SomeImportantLabel'。

您可以使用 ANY/ALL/SINGLE/NONE 函数在 WHERE 部分过滤路径结果,Neo4j 可以在搜索路径时应用这些过滤器(如果需要至少 ALL/NONE)。

例如……

MATCH p = allShortestPaths((a)-[*]-(c))
WHERE ID(a) = 123 AND ID(c) = 456 
AND ANY(b in NODES(p) WHERE a<>b<>c AND b:SomeImportantLabel)  
RETURN nodes(p) as nodes, relationships(p) as rels;

此外,虽然我们可以从 ANY 的过滤器集中截断列表的 head/tail,但 Cypher 规划器喜欢将相同的过滤器应用于整个路径,因此最好将它们排除在哪里部分。