找到一组肯定包含至少一个具有特定属性值的子集的节点

Posted

技术标签:

【中文标题】找到一组肯定包含至少一个具有特定属性值的子集的节点【英文标题】:Find a set of nodes containing certainly at least one subset having a certain property value 【发布时间】:2018-07-18 20:39:13 【问题描述】:

我需要一个 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 

将仅返回一组标识符,其中仅包含一个子集 THAT VERIFY c.identifier='504'

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

我想获得至少在结果子集中包含一个验证属性值的子集的集合。

我尝试了 where EXISTS,但不幸的是我无法得到我想要的。

MATCH (c:C)-[:BELONGING_TO]->(r:R)-[r*0..1]-(s:S) 
WHERE EXISTS((s)-[*0..]-(cidentifier:'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 cidentifier:'504'
   ---------s2 have property cidentifier:'504'
   ---------s3 have property cidentifier:'504'
----C2
   ---------s21 have property cidentifier:'21'
   ---------s22 have property cidentifier:'21'
   ---------s23 have property cidentifier:'21'
----C3
    ----------s31 have property cidentifier:'23'
    ----------s32 have property cidentifier:'23'
    ----------s33 have property cidentifier:'23'

另外一个 Hierarchy2 与 R,C1,C2,C3 同名

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

当我做我的密码时,我应该让所有节点 s1,s2,s3,s21,s22,s23,s31,s32,s33 包含在层次结构 1 中,而不是来自层次结构 2,因为在层次结构 1 中我至少有一个子集节点 s1、s2 ,s3 具有属性 cidentifier:'504' 在层次结构 2 中没有人有 cidentifier:'504',所以第二个层次结构将被我的密码忽略。

密码将确保我只从层次结构1 中获得 s 并且没有来自hierarchy2的s。

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

【问题讨论】:

仍在尝试了解您在这里的目的。你的意思是你想要s 节点(或其标识符),其中只有一个s 节点链接到标识符为“504”的 :C 节点,其余的则不是? 谢谢 InverseFalcon 。没有那些链接到带有标识符“504”、“708”、“908”......等的 :C 节点的 s 节点,但我确信我的密码将确保至少产生一个带有标识符“504”的节点链接到 :C 节点的 s 节点的结果子集。 . 标识符“504”作为参数传递给密码请求。 因此生成的s 节点将链接到各种c 节点。鉴于标题中的 at least/ at most 描述,您似乎只希望将其中一个 s 节点与标识符为 504 的 c 节点链接,对其余节点没有限制(只是它们也不能与c 节点 504 链接)。那是对的吗?或者您想通过c 节点对s 节点进行分组,这样您将拥有一个与c 节点504 链接的s 节点列表,其余的则与其他c 节点链接? 第二个选项意味着我想按它们的 c 节点对 s 节点进行分组,所以我将有一个与 c 节点 504 链接的 s 节点列表,其余的与其他 c 节点链接,但我很确定至少得到一个与 c 节点 504 链接的 s 节点列表。我将更新我的问题以澄清这一点,请参阅问题的底部。 【参考方案1】:

我想我知道你想要什么。

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

但首先我们必须处理过滤,以确保我们只选择与标识符为 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

【讨论】:

非常感谢 InverseFalcon。经过测试,它像魅力一样完美运行。

以上是关于找到一组肯定包含至少一个具有特定属性值的子集的节点的主要内容,如果未能解决你的问题,请参考以下文章

xpath按元素和属性查找节点,其中包含具有特定id的子元素

Grails:查找具有列表属性的对象,其中包含具有给定属性值的对象

如何从对象数组中获取具有属性的列表,除非它包含具有特定值的另一个项目?

查找是不是在列表中找到具有特定属性值的元素

如何找到具有特定“类型”属性值的 <script> 元素?

Oracle SQL - 过滤掉包含具有特定值的行的分区或行组