在 Neo4J 中获取从某个节点到给定标签的任何节点的最短路径

时间:2021-04-21 07:58:27

标签: neo4j

我有一个节点,我们称之为X。我想找到离X最近的节点,我们将它命名为Y,Y必须有一个特定的标签。如果有多个这样的 Y 节点与 X 的距离相同,我希望它们都返回

假设我们有某个标签的节点 A 和 B。从 X 到 A 的最小路径长度为 3,从 X 到 B 的最小路径长度为 5。我希望它返回 A 并且只返回 A。如果最小路径长度相等,我希望它同时返回它们(A 和乙)

这是我目前所拥有的:

MATCH p=shortestPath((selectedNode {name:'X'})-[*]-(y:GivenLabel))
WITH y.name as y, length(p)=min(length(p)) AS l
RETURN y

这个查询的问题是在上面的例子中它同时返回 A 和 B,不管它们的最小路径是什么。我想过使用 LIMIT 1 并对它们进行排序,但它只会显示其中之一,即使它们中的每一个的最小路径长度相等

提前致谢!

2 个答案:

答案 0 :(得分:0)

collect 函数可让您返回包含值列表的单行。

MATCH p=shortestPath((selectedNode {name:'X'})-[*]-(y:GivenLabel))
RETURN length(p) AS l, collect(y.name) as targets
ORDER BY l
LIMIT 1

如果要将值作为单个记录而不是列表返回,可以使用 UWIND

MATCH p=shortestPath((selectedNode {name:'X'})-[*]-(y:GivenLabel))
WITH length(p) AS l, collect(y.name) as targets
ORDER BY l
LIMIT 1
UNWIND targets as target
RETURN l, target

答案 1 :(得分:0)

如果您有 APOC 程序,您可以使用路径扩展程序之一来查找给定标签的最短路径并对其进行限制。不幸的是,您需要再次调用才能在相同距离内获取标签的多个节点。

// assume we've already MATCHed to selectedNode
...
CALL apoc.path.expandConfig(selectedNode, {labelFilter:'/GivenLabel', limit:1}) YIELD path
WITH selectedNode, length(path) as pathLength
CALL apoc.path.subgraphNodes(selectedNode, {labelFilter:'/GivenLabel', maxLevel:pathLength}) YIELD node
RETURN node

在标签过滤器中,前缀/表示标签将用于终止过滤器,一旦找到第一次出现就停止扩展,并使用该节点作为结果。

路径扩展过程默认使用广度优先扩展,因此它将是从起始节点到给定标签的节点的最短路径。

limit:1 确保我们在找到第一个结果后返回(如果给定标签没有这样的节点,或者距离很远,这可能会非常昂贵,因此您可以考虑提供一个 {{1} } 作为上限)。

我们使用先前找到的路径长度作为我们的 maxLevel 进行类似的路径扩展器调用(subgraphNodes(),因为我们不再需要路径,只需要末尾的节点),这将返回具有给定的所有节点在那个距离标记。