Neo4j-通过节点的最短路径

时间:2018-10-24 15:18:15

标签: neo4j cypher shortest-path

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

(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)之间找到两条最短路径,它们经过带有标签'SomeImportantLabel'的节点(b)

1 个答案:

答案 0 :(得分:1)

您可以使用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过滤器集中截断列表的头/尾,但是Cypher计划者喜欢将同一过滤器应用于整个路径,因此最好在WHERE部分中将它们排除在外。 / p>