我想返回所有节点 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
答案 0 :(得分:2)
我们可以使用WHERE NOT
以与您的第二个半伪代码类似的方式制定负面条件:
MATCH (a)-[*]->(b)
WHERE NOT ((a)-[:rel]->()-[*1..]->(b))
RETURN a, b
当然,这将是有效的,所以您至少应该尝试限制a
和b
的标签以及它们之间的关系,例如(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)
查询结果为:
╒══════════╤══════════╕
│a │b │
╞══════════╪══════════╡
│{name: n1}│{name: n2}│
├──────────┼──────────┤
│{name: n4}│{name: n5}│
└──────────┴──────────┘
正如您所看到的,它不包括n3
和n5
,因为它以: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;