Neo4j查询与关系类型的逻辑AND而不是OR

时间:2016-07-20 21:39:53

标签: neo4j cypher

更新 :我更改了图形和示例查询,以使请求更加清晰。基本的想法是一样的,但现在我表明,真的不仅仅是两种关系。这个想法是我希望它们中的两个匹配,不一定全部匹配。

给出以下Neo4j图:

Two nodes with many relationships

是否可以在查询中指定一个关系,该关系要求 TWO 特定关系用于匹配,但不一定全部,而不是单独说明每个完整匹配路径?我想在关系类型上使用逻辑AND,就像我们使用OR字符的逻辑|一样。

这就是你如何使用|字符的逻辑OR:

// OR on MEMBER_OF and GRANT_GROUP_COMP
MATCH (p:Person {name:'John'})-[r:MEMBER_OF|GRANT_GROUP_COMP]->(t:Team {name:'Team 1'})
RETURN p,r,t

我正在寻找的是这样的东西,一个带有&的AND或者需要的两个关系存在的

// AND type functionality in the relationship I'd like
MATCH (p:Person {name:'John'})-[r:MEMBER_OF&GRANT_GROUP_COMP]->(t:Team {name:'Team 1'})
RETURN p,r,t

不必诉诸于此 - 对我来说很合适

// I'd like to avoid this
MATCH (p:Person {name:'John'})-[r:MEMBER_OF]->(t:Team {name:'Team 1'}),
  (p)-[r2:GRANT_GROUP_COMP]->(t)
RETURN p,r,r2,t

任何见解都会受到赞赏,但基于到目前为止的回复,它根本就不存在。

3 个答案:

答案 0 :(得分:2)

这个怎么样?

MATCH (D:Person {name:'Donald'})-[r1:WORKS_AT]->
      (o:Office {code:'279'})<-[r2:SUPPORTS]-(D)
RETURN *

Dave的灵感版本

MATCH (D:Person {name:'Donald'})-[r:WORKS_AT|SUPPORTS]->(o:Office {code:'279'})
WITH D, o, collect(r) as rels, 
     collect(distinct type(r)) as tmp WHERE size(tmp) >= 2
return D, o, rels

<强>更新

MATCH (D:Person {name:'Donald'})
      -  [r: MEMBER_OF
           | GRANT_INDIRECT_ALERTS
           | GRANT_INDIRECT_COMP
           | GRANT_GROUP_ALERTS
           | GRANT_GROUP_COMP 
         ] ->
      (o:Office {code:'279'})
WITH D, o, collect(r) as rels, 
     collect(distinct type(r)) as tmp WHERE size(tmp) >= 2 AND size(tmp) <= 5
return D, o, rels

答案 1 :(得分:2)

如果JohnTeam 1之间存在MEMBER_OFGRANT_GROUP_COMP关系,此查询将返回结果。

(这与@ stdob--的第二个答案非常相似,但要求types的大小正好为2。)

MATCH (p:Person {name: 'John'})-[r:MEMBER_OF|GRANT_GROUP_COMP]->(t:Team {name: 'Team 1'})
WITH p, t, COLLECT(r) AS rels, COLLECT(DISTINCT type(r)) AS types
WHERE SIZE(types) = 2
RETURN p, t, rels;

答案 2 :(得分:1)

您可以在WHERE子句中添加第二种关系类型。像这样......

MATCH (p:Person {name:'John'})-[r:GRANT_GROUP_COMP]->(t:Team {name:'Team 1'})
WHERE (p)-[:MEMBER_OF]->(t)
RETURN *

或者您可以确保完整集合位于关系类型集合中。像这样......

MATCH (p:Person {name:'John'})-[r]->(t:Team {name:'Team 1'})
with p,t,collect(type(r)) as r_types
where all(r in ['MEMBER_OF','GRANT_GROUP_COMP'] where r in r_types)
RETURN p, t, r_types