在关系类型上使用逻辑AND而不是OR的Neo4j查询

在关系类型上使用逻辑AND而不是OR的Neo4j查询,neo4j,cypher,Neo4j,Cypher,更新:我已经更改了图形和示例查询,以使请求更加清晰。基本的想法是一样的,但现在我要展示的是,真正存在的不仅仅是两种关系。我的想法是,我希望其中两个匹配,而不一定是全部匹配 给出以下Neo4j图: 是否可以在查询中指定一个关系,该查询要求存在两个特定的关系进行匹配,但不一定全部匹配,而不单独声明每个完整匹配路径?我希望在关系类型上有一个逻辑和,就像我们有一个使用|字符的逻辑或 这就是将逻辑OR与|字符一起使用的方式: // OR on MEMBER_OF and GRANT_GROUP_COMP

更新:我已经更改了图形和示例查询,以使请求更加清晰。基本的想法是一样的,但现在我要展示的是,真正存在的不仅仅是两种关系。我的想法是,我希望其中两个匹配,而不一定是全部匹配

给出以下Neo4j图:

是否可以在查询中指定一个关系,该查询要求存在两个特定的关系进行匹配,但不一定全部匹配,而不单独声明每个完整匹配路径?我希望在关系类型上有一个逻辑
,就像我们有一个使用
|
字符的逻辑

这就是将逻辑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和一个
&
或simlar,要求两种关系都存在:

// 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
不必求助于这一点——这对我来说很好:


任何洞察都是值得赞赏的,但根据目前为止的回答,它根本不存在。

您可以在
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
或者,您可以确保完整的集合位于关系类型的集合中。像这样的

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
这个怎么样

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

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
MATCH(D:Person{name:'Donald'})
-[r:
|授予\u间接\u警报
|授予间接薪酬
|授予组警报
|格兰特集团公司
] ->
(o:办公室{代码:'279'})
D,o,collect(r)作为rels,

收集(不同类型(r))作为tmp,其中大小(tmp)>=2和大小(tmp)如果
John
Team 1
之间有
成员关系和
授予组成员关系,则此查询将返回结果

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


我很欣赏这些想法,尤其是第二个想法,但我问这个问题的原因是,我试图摆脱一个我已经拥有的模型,而是在关系中使用属性,并使用WHERE来检查它们。我想要一个更清晰/更简单的查询。我想您的第二个想法至少有一个好处,就是不在WHERE中使用属性,据我所知,这有点提高了性能。我相信,属性与关系类型在文件系统的不同部分。根据您的数据统计数据,第一个属性具有更好的性能。如果您有一种关系类型出现的次数少于另一种,并且您将其放在匹配语句中,那么如果没有手表,neo4j将不会计算超过该值。然而,如果获取两个节点之间的所有关系类型并对它们进行评估,则会导致更多的数据库命中。如果整体数据很小,或者关系类型出现的次数是偶数,则该点可能是静音的。这是很好的反馈,Dave。我真的很感激。我的团队对使用Neo4j还不熟悉,所以这样的见解确实很有帮助。第一种方法的问题是,它只适用于简单的示例。我的实际需求在(o:Office)节点的另一端已经有了其他东西。在您的第二个示例中,它假设那里只有两个关系,而在我的例子中,我正在检查是否存在多个关系中的特定两个。不过,这很聪明。@MichaelOryl在第二种解决方案中,你可以添加任意多种类型的关系,你想要多少:
MATCH(D:Person{name:'Donald})-[r:WORKS_AT | SUPPORTS | REL1 | REL2 | REL3]>(o:Office{code:'279})与D,o匹配,collect(r)作为rels,collect(distinct type(r))作为tmp,其中size(tmp)>=5返回D,o,rels
这是真的,但我的意思是有很多,但我只关心两个具体的,不是所有的都有。我的用例是访问权限。考虑一下,我希望看到某个人是一个团队的成员,并将这个群体授予他或她的数据的一个特定类别。我希望两个关系都与查询匹配。但该用户也可能授予该组其他类别的数据权限。跟我来?我已经用新的图形和示例查询更新了问题。@MichaelOryl f我理解正确-请参阅我的更新版本。
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;