知识库

使用 Cypher 实现 longestPath(最长路径)

虽然 Cypher 针对在两个节点之间寻找最短路径进行了优化,提供了如 shortestPath() 的功能,但它并没有相同的最长路径函数。在某些情况下,你可能需要最长路径,而不是最短路径。

树中的根到叶子

如果你有一棵树结构,想要找到根节点到叶子节点之间的最长路径,并且不知道中间有多少层节点

MATCH p=(parent:Root)-[r:HAS_CHILD*1..10]->(child:Node)
RETURN p

问题在于它会返回所有路径,每跳一次就产生一条,直到到达叶子节点。你想要的只是最长的那条路径,以查看父节点与叶子子节点是如何相连的。要高效实现,请按以下步骤操作

MATCH p=(parent:Root)-[:HAS_CHILD*1..10]->(child:Node)
WHERE NOT (child)-[:HAS_CHILD]->()
RETURN p

上面查询的作用:变量长度 1..10 会查找所有路径(理论上只有一条),即最长不超过 10 跳的任意父子路径。WHERE 子句用于过滤,只保留叶子子节点没有外向 :HAS_CHILD 关系的路径(即找到链的末端)。

存在多条路径时的最长路径

如果不是使用无环树结构,两个节点之间可能存在多条路径,此时你可能只想要最长的一条。我们可以通过按路径长度排序并仅保留最长路径来实现。

MATCH p=(start:Node)-[:REL*1..10]->(end:Node)
WHERE id(start) = 123 AND id(end) = 456
RETURN p
ORDER BY length(p) DESC
LIMIT 1

提高这些查询效率的技巧

在一个相当连通的图中,这类可变长度路径查询可能会变得越来越昂贵。以下是保持查询性能的一些技巧。

  1. 约束关系类型和方向——如果可能,只使用所需的相关类型,并使用有方向的关系。这可以减少展开时遍历的路径数量。

  2. 为可变长度模式提供上限——在高度连通的图中,没有上限的模式可能会失控。设置上限可以帮助限制查询需要执行的工作量。

  3. 在 MATCH 之后的 WHERE 子句中使用 all()none()——如果谓词需要在展开期间评估,并且必须适用于路径中的所有节点或关系,请在路径的节点或关系上使用 all()none(),这样可以在展开时进行评估,而不是在找到所有路径后再过滤。

  4. 对特殊情况或限制使用 APOC 路径扩展器——对于某些限制,例如在展开时不重复节点,你可以使用来自 APOC Procedures 的路径扩展过程,以在展开期间强制不同的唯一性配置。

© . This site is unofficial and not affiliated with Neo4j, Inc.