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 规划器喜欢将相同的过滤器应用于整个路径,因此最好将它们排除在哪里部分。
我正在尝试通过具有标签 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 规划器喜欢将相同的过滤器应用于整个路径,因此最好将它们排除在哪里部分。