获取子图不穿越特定节点

时间:2018-12-20 15:49:16

标签: neo4j cypher

我有一个巨大的图(非循环图),并且想找到从给定节点通过关系X可到达的所有节点。但是,我不想穿越具有特定属性{attr:'donotcross'}的节点,因为这代表了我不想穿越的阻塞点(即,这是通往相邻子图的唯一节点)。

目前,我会先使用简单的Cypher查询来广度搜索自己,以隔离相邻节点和python,并在到达该特定节点后立即停止递归。但是,这确实很慢,我认为使用纯Cypher隔离那些节点可能会更快。

Cypher查询看起来像通过X返回所有连接的节点但不遍历具有属性attr:'donotcross'的节点吗?

我的直觉是

MATCH (n)-[:X*]->(inter)-[:X*]->(m) WHERE NOT inter.attr = 'donotcross' RETURN m

以n为起始节点。但是,这不起作用,因为如果在起始节点和目标节点之间存在比禁止节点更多的路径,则该模式可以将路径与禁止节点匹配。

1 个答案:

答案 0 :(得分:1)

单独使用Cypher,您可以使用以下方法:

MATCH path = (n)-[:X*]->(m) // best to use a label!
WHERE none(node in nodes(path) WHERE inter.attr = 'donotcross')
RETURN DISTINCT m

请记住,如果无法通过特定标签的索引属性查找标签,则至少应为起始节点n使用标签。

如果这些donotcross节点相对较少,并且attr上这些节点的标签上有一个索引,那么在这些节点上进行首次匹配可能会更快,收集它们,然后基于此进行过滤:

MATCH (x) // best to use a label and index lookup!
WHERE x.attr = 'donotcross'
WITH collect(x) as excluded
MATCH path = (n)-[:X*]->(m) // best to use a label!
WHERE none(node in nodes(path) WHERE node in excluded) 
RETURN DISTINCT m