首页 > 解决方案 > 获取不穿过某个节点的子图

问题描述

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

目前,我使用简单的 Cypher 查询进行广度优先搜索,以隔离相邻节点和 python,一旦到达该特定节点就停止递归。然而,这真的很慢,我认为使用纯 Cypher 来隔离这些节点可能会更快。

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

我的直觉是

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

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

标签: neo4jcypher

解决方案


单独使用 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

推荐阅读