查找一组节点,这些节点包含至少一个具有特定属性值的子集

时间:2018-07-18 20:39:13

标签: neo4j cypher where exists

我需要一个Cypher帮助,以确保所生成的一组节点中至少包含一个验证特定属性值的子集。

每个结果集都包含子集。

作为结果,我想要的目标集应该至少在结果子集中具有验证属性值的子集。

假设我有:

R包括C包括S

那是

(c:C)-[:BELONGING_TO]->(r:R)-[r*0..1]-(s:S)

假设

    R={r1,r2,r3,...........rn} 
    C={c1,c2,c3,...........cn}
    S={sb1,sb2,sb3,...........sbn}

where sb1={s11,s12,s13.....s1n}
      sb2={s21,s22,s23.....s2n}
      sb3={s31,s32,s33.....s3n}
      .........................
      sbn={sn1,sn2,sn3.....snn}

例如

MATCH (c:C)-[:BELONGING_TO]->(r:R)-[r*0..1]-(s:S) 
WHERE 
r.r='BLABLA' AND 
r.identifier='50' AND
c.identifier='504' 
return s.identifier as identifier 

将仅返回一组仅包含一个已验证c.identifier ='504'的标识符

并且我想返回一个包含所有子集的集合(即,验证rr ='BLABLA'和r.identifier = '50'),并且在这些结果子集中肯定有至少一个子集可以验证c.identifier ='504'。

我要获得的集合至少可以肯定地包含一个验证属性值的子集。

我尝试了存在的地方,但不幸的是我无法得到想要的东西。

MATCH (c:C)-[:BELONGING_TO]->(r:R)-[r*0..1]-(s:S) 
WHERE EXISTS((s)-[*0..]-(c{identifier:'504'})) 
AND 
r.r='BLABLA' 
AND 
r.identifier='50'

N.B:节点之间的关系如下:

(s:S)-[rel1:IS_A_S_BELONGING_TO_R*0..1]->(r:R)<-[rel2:IS_A_C_BELONGING_TO*0..1]-(c:C)<-[IS_A_S_BELONGING_TO_THAT_C*0..1]-(s) 

非常感谢您的帮助。

更新

假设我具有等级1

R----
----C1
   ---------s1 have property c{identifier:'504'}
   ---------s2 have property c{identifier:'504'}
   ---------s3 have property c{identifier:'504'}
----C2
   ---------s21 have property c{identifier:'21'}
   ---------s22 have property c{identifier:'21'}
   ---------s23 have property c{identifier:'21'}
----C3
    ----------s31 have property c{identifier:'23'}
    ----------s32 have property c{identifier:'23'}
    ----------s33 have property c{identifier:'23'}

另一个具有与R,C1,C2,C3相同名称的Hierarchy2

R----
----C1
   ---------s1 DON't have property c{identifier:'504'}**********
   ---------s2 DON't have property c{identifier:'504'}**********
   ---------s3 DON't have property c{identifier:'504'}**********
----C2
   ---------s21 DON't have property c{identifier:'504'}**********
   ---------s22 DON't have property c{identifier:'504'}**********
   ---------s23 DON't have property c{identifier:'504'}**********
----C3
    ----------s31 DON't have property c{identifier:'504'}**********
    ----------s32 DON't have property c{identifier:'504'}**********
    ----------s33 DON't have property c{identifier:'504'}**********

当我执行密码时,我应该获得包括在等级1中的所有节点s1,s2,s3,s21,s22,s23,s31,s32,s33,而不是从等级2中获得,因为在等级1中我至少有一个子集节点s1,s2 ,s3具有属性c {identifier:'504'} 在等级2中,没有人使用c {identifier:'504'},因此第二个等级将被我的密码忽略。

密码将确保我仅从hierarchy1中包含s 也没有来自分级2的。

因为R,C1,C2,C3名称可以在许多层次结构中重复,并且我有一个参数c {identifier:XXXX}密码,可以区分它们。

1 个答案:

答案 0 :(得分:1)

我想我能满足您的需求。

这里缺少的部分是s节点按其c节点的分组。您将要在此处使用collect()s节点收集到列表中,并通过将c节点保留为非聚合变量来确保s节点按其相关的c节点分组。

但是首先我们必须处理过滤,以确保我们只选择与标识符为504的:C节点匹配的:R节点。听起来像您很少(或也许只有一个?):C节点标识符为504,因此,请确保我们只选择链接到有问题的:C节点的:R节点,然后在过滤后继续到:S节点。

请注意,您在查询中两次使用了r变量,一次是用于:R节点,另一次是与s节点的可选关系,因此不会工作。我们可以从关系中删除变量。

MATCH (c:C)
WHERE c.identifier='504'
MATCH (r:R)
WHERE 
r.r='BLABLA' AND 
r.identifier='50' AND
(c)-[:BELONGING_TO]->(r)
WITH r
MATCH (c:C)-[:BELONGING_TO]->(r)-[*0..1]-(s:S)
WITH c, collect(DISTINCT s) as sList
RETURN c.identifier as cId, [s in sList | s.identifier] as sList