如何获取所有连接的节点,不包括特定的关系

时间:2018-11-30 17:20:57

标签: graph neo4j cypher

我正在寻找一种检索所有连接节点的高性能方法。 但是有一个转折。我想排除通过某些关系类型连接的节点和子节点。

附图说明了我的情况。

有两个或多个节点簇。我想检索单个群集的所有节点,具体取决于查询中的ID。 不包括通过“ LINK ...”关系连接的所有其他节点(来自不同群集)。

我知道如何通过以下方式检索所有连接的节点:

MATCH (n:MyNode {id : 123})-[*]-(connectedNodes) RETURN connectedNodes

使用WHERE子句进行过滤听起来像是一个坏主意,因为它仍将获取整个图形。 APOC程序中是否有某些东西可以让我以这种方式做某事?非常感谢您的帮助。

编辑1:沙发手我尝试了注释中给出的第一个建议,但是执行时间不够。毕竟,我将尝试限制关联和节点类型。我也尝试了使用递归函数在Python中自定义实现。尚未完成。

编辑2:@InverseFalcon的建议很奏效。首先过滤一次将不考虑的所有可用关系类型,然后对相应的起始节点和有效关系类型应用apoc.path.subgraphNodes过程。谢谢。 enter image description here

2 个答案:

答案 0 :(得分:2)

Tezra的答案很不错,您将需要返回DISTINCT connectedNodes,否则将得到重复的副本,但是在高度连接的图上,这可能需要一段时间(甚至挂起),具体取决于节点的数量,因为Cypher对所有可能的比赛路径都感兴趣,而且很快就会失去控制。

对于APOC,我们可以处理这种情况,但是正如Tezra所说,我们没有办法将关系列入黑名单,即使有,我们也没有办法根据关系类型的部分名称将其列入黑名单

您需要使用的方法是首先获取所有关系类型,然后删除以LINK开头的所有关系类型,然后将其余关系列表加入到|分隔的字符串中。然后,您可以将其传递给关系过滤器。

CALL db.relationshipTypes() YIELD relationshipType
WHERE NOT relationshipType STARTS WITH 'LINK'
WITH collect(relationshipType) as relTypes
WITH apoc.text.join(relTypes, '|') as relTypesString
MATCH (n:MyNode {id : 123})
CALL apoc.path.subgraphNodes(n, {relationshipFilter:relTypesString}) YIELD node
RETURN node as connectedNode

答案 1 :(得分:1)

首先,我想强调的是Cypher并不限制信息的检索方式,它仅确定返回的信息。因此,在排除此问题之前,请尝试使用WHERE(此外,请尝试升级到最新的Neo4j,以获得最聪明的密码计划者)。这应该可以正常工作,因为密码计划器可以在匹配结果时过滤结果。

MATCH (n:MyNode {id : 123})-[rs*]-(connectedNodes)
WHERE NONE(r in rs WHERE TYPE(r)="LINK")
RETURN DISTINCT connectedNodes

我可以想到的APOC过程要求您命名所使用的关系(可以将标签列入黑名单,但似乎不适用于关系类型),因此与{{1} }