Cypher:量化零或多个节点然后关系

时间:2016-12-10 13:55:06

标签: neo4j cypher graph-databases

我想返回所有节点 a b ,其中 b 不是 a 的下游以关系 rel 开头的路径。我一直发现自己必须为 a 通过 rel 直接链接到 b 的情况编写一个条件,并为间接情况编写一个条件,导致这样的事情:

//Semi-pseudo-code.
match           (a)-[*]->(b)
optional match  dir=(a)-[:rel]->(b)
optional match  indir=(a)-[:rel]-()-[*]->(b)
where           length(dir)=0
and             length(indir)=0
return          a,b

有没有更简单的方法?我真的想要这样的东西,其中裸量词意味着"零个或多个节点 - 然后关系":

match           (a)-[*]->(b)
match not       (a)-[:rel]-*->(b)
return          a,b

注意:我怀疑这可能与我的上一个问题相同:Cypher: Matching nodes at arbitrary depth via a strictly alternating set of relations

2 个答案:

答案 0 :(得分:2)

我们可以使用WHERE NOT以与您的第二个半伪代码类似的方式制定负面条件:

MATCH     (a)-[*]->(b)
WHERE NOT ((a)-[:rel]->()-[*1..]->(b))
RETURN    a, b

当然,这将是有效的,所以您至少应该尝试限制ab的标签以及它们之间的关系,例如(a:Label1)-[:rel1|rel2*]->(b:Label2)

一个例子:

CREATE
  (n1:N {name: "n1"}),
  (n2:N {name: "n2"}),
  (n3:N {name: "n3"}),
  (n4:N {name: "n4"}),
  (n5:N {name: "n5"}),
  (n1)-[:x]->(n2),
  (n3)-[:rel]->(n4),
  (n4)-[:x]->(n5)

enter image description here

查询结果为:

╒══════════╤══════════╕
│a         │b         │
╞══════════╪══════════╡
│{name: n1}│{name: n2}│
├──────────┼──────────┤
│{name: n4}│{name: n5}│
└──────────┴──────────┘

正如您所看到的,它不包括n3n5,因为它以:rel关系开头。

答案 1 :(得分:1)

这应该有效:

MATCH (a)-[rs*]->(b)
WHERE TYPE(rs[0]) <> 'rel'
RETURN a, b;

但是,下面的查询应该更加高效,因为它会在之前过滤掉所有不需要的路径,它会进行非常昂贵的可变长度路径搜索。 *0..语法使得可变长度搜索使用长度为0的下限(因此x也可以作为b返回)。

MATCH (a)-[r]->(x)
WHERE TYPE(r) <> 'rel'
MATCH (x)-[*0..]->(b)
RETURN a, b;