我有一个巨大的图(非循环图),并且想找到从给定节点通过关系X
可到达的所有节点。但是,我不想穿越具有特定属性{attr:'donotcross'}
的节点,因为这代表了我不想穿越的阻塞点(即,这是通往相邻子图的唯一节点)。
目前,我会先使用简单的Cypher查询来广度搜索自己,以隔离相邻节点和python,并在到达该特定节点后立即停止递归。但是,这确实很慢,我认为使用纯Cypher隔离那些节点可能会更快。
Cypher查询看起来像通过X返回所有连接的节点但不遍历具有属性attr:'donotcross'
的节点吗?
我的直觉是
MATCH (n)-[:X*]->(inter)-[:X*]->(m) WHERE NOT inter.attr = 'donotcross' RETURN m
以n为起始节点。但是,这不起作用,因为如果在起始节点和目标节点之间存在比禁止节点更多的路径,则该模式可以将路径与禁止节点匹配。
答案 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