使用 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
提高这些查询效率的技巧
在一个相当连通的图中,这类可变长度路径查询可能会变得越来越昂贵。以下是保持查询性能的一些技巧。
-
约束关系类型和方向——如果可能,只使用所需的相关类型,并使用有方向的关系。这可以减少展开时遍历的路径数量。
-
为可变长度模式提供上限——在高度连通的图中,没有上限的模式可能会失控。设置上限可以帮助限制查询需要执行的工作量。
-
在 MATCH 之后的 WHERE 子句中使用
all()或none()——如果谓词需要在展开期间评估,并且必须适用于路径中的所有节点或关系,请在路径的节点或关系上使用all()或none(),这样可以在展开时进行评估,而不是在找到所有路径后再过滤。 -
对特殊情况或限制使用 APOC 路径扩展器——对于某些限制,例如在展开时不重复节点,你可以使用来自 APOC Procedures 的路径扩展过程,以在展开期间强制不同的唯一性配置。
此页面有帮助吗?