为了高效地匹配可达节点,有两个选项通常表现得很好。
在Neo4j 3.2.x中,通过变量关系匹配加上DISTINCT的使用,有一种有效的方法可以匹配到所有不同的可达节点,但需要对变长关系设置一个上限。使用适当高的数字应该就可以了。例如:
MATCH (:SomeLabel{someProperty:false})-[*..999999]->(x)
WITH distinct x
SET x.someProperty = false
MATCH (start:SomeLabel{someProperty:false})
CALL apoc.path.subgraphNodes(start, {}) YIELD node
SET node.someProperty = false;
编辑
为了对第一个选项(为什么不使用*
,而是使用DISTINCT)添加更多细节,请记住,当我们使用*
时,默认情况下,Cypher将匹配到所有可能的路径,即使这些路径以前已经在同一节点处结束。如果图形连接得足够复杂(当我们没有合理的上限并且我们没有使用LIMIT时),这可能会变得效率低下,有可能导致堆溢出或无限期挂起。
当我们不仅仅关心所有可能的路径,而只关心所有可达节点时,应该避免这种情况。
在Neo4j 3.2中引入了一种优化,称为修剪-var expand,在以下所有情况均为真时更改遍历逻辑:
基本上,当查询明确表明我们希望从var-length扩展获得不同节点(或来自不同节点的值)并且不关心路径时,会使用修剪var expand(您可以通过从EXPLAIN或PROFILE中检查查询计划来确认)高效地匹配可达节点。
计划者将使用修剪var expand,以便有效匹配到可达节点。
*
以及修剪变量扩展优化的限制的详细信息。 - InverseFalcon我不确定我完全理解了你的问题,但我相信一个简单的Cypher查询就足够了。类似这样:
MATCH ({someProperty : false})-[*]-(neighbours)
SET neighbours.someProperty = false