Node4j在子图中获得多级关系节点

时间:2017-04-28 22:17:06

标签: neo4j cypher graph-databases

我想在子图中获取关系中的节点 例如:

A-BELONGS->B
B-BELONGS->C
C-REQUIRES->B
C-REQUIRES->H
B-REQUIRES->P

所以我想从A开始,以递归方式得到所有具有BELONGS关系的节点,即A,B,C,然后获得与那些节点处于REQUIRES关系但不在BELONGS关系子图中的节点,即H和P,但不是B.但我想只返回一个REQUIRES关系中的那些节点。

我写了这样的查询:

MATCH (node:Node {name: 'A'})-[:BELONGS*]->(dep)
USING collect(node) + collect(dep) as nodes
WITH (dep)-[:REQUIRES]->(req)
return disinct req

在这里,我希望只得到P和H.但这不是我得到的。这个查询出了什么问题?

2 个答案:

答案 0 :(得分:1)

您的查询中存在大量语法错误。即使我们修复了这些问题,基本逻辑也存在缺陷,因为(dep)-[:REQUIRES]->(req)模式甚至不使用任何明确定义的标识符(nodedepnodes并且它也不使用可变长度关系模式。

这应该有效:

MATCH p=(node:Node {name: 'A'})-[:BELONGS*]->(dep)
WITH NODES(p) AS nodes
UNWIND nodes AS n
WITH COLLECT(DISTINCT n) AS ns
UNWIND ns AS nd
MATCH (nd)-[:REQUIRES*]->(req)
WHERE NOT req IN ns
RETURN DISTINCT req;

此查询首先匹配所有相关的BELONGS路径(到任何深度),删除重复的节点,并将节点收集到单个ns集合中。然后,它使用每个节点来获取REQUIRES路径(到任何深度)的节点,这些节点不在ns中。最后,它返回不同的结果节点。

答案 1 :(得分:1)

根据您的描述,您的数据集如下所示:

enter image description here

我的解决方案,根据您的问题描述一步一步:

  

所以我想从A开始,以递归方式获取所有具有的节点   BELONGS关系,即A,B,C,

MATCH (a:Node {name:'A'})-[:BELONGS*]->(n)
WITH a + collect(n) as nodes
UNWIND nodes as unwinded
  

然后得到与那些节点处于REQUIRES关系的节点   不是在BELONGS关系子图中,即H和P,而不是B.但是我   想要只返回REQUIRES关系中的那些节点。

MATCH(unwinded)-[:REQUIRES]->(m)
WHERE NOT m IN nodes
RETURN m

生成的Cypher查询是:

MATCH (a:Node {name:'A'})-[:BELONGS*]->(n)
WITH a + collect(n) as nodes
UNWIND nodes as unwinded
MATCH(unwinded)-[:REQUIRES]->(m)
WHERE NOT m IN nodes
RETURN m

使用PROFILE运行此查询会显示22 db命中。剖析cybersam描述的查询显示27 db命中。从第一眼看和非常肤浅的方式来看,这个查询对我来说成本更低。