首页 > 解决方案 > Cypher 选择任何邻居不包含属性的顶点

问题描述

在此处输入图像描述

{
    "identity": 7,
    "labels": [
        "Parent"
    ],
    "properties": {
        "name": "foo1"
    }
}, 
{
    "identity": 8,
    "labels": [
        "Child"
    ],
    "properties": {
        "name": "bar2"
    }
}, 
{
    "identity": 9,
    "labels": [
        "Child"
    ],
    "properties": {
        "name": "bar1"
    }
}, 
{
    "identity": 10,
    "labels": [
        "Parent"
    ],
    "properties": {
        "name": "foo2"
    }
}

我想选择没有孩子父母name='abc'

预期行为:我应该得到父母 (foo1foo2) 作为结果

查询1:

Match (x1:Parent) with x1 
optional Match (x1)-[:CHILD]-(x2:Child) with x1 , collect(x2) as x3 
UNWIND x3 as x2 
WITH x1 , x2 , x3 
where none (x IN  x3 where x.name IN ['abc']) 
return DISTINCT x1 

这个查询只返回 1 个 Parent( foo1),但它应该返回两个父母,并且第二个 parent( foo2) 没有连接到任何孩子。

PS:使用的原因UNWIND是将变量用于变量的进一步WHERE子句x2

标签: neo4jcypher

解决方案


这将得到所有没有孩子名字的父母:'abc'或没有任何孩子

MATCH (p:Parent)
WHERE NOT EXISTS((p)-[:CHILD]->(:Child {name: 'abc'}))
RETURN p 

检查给定的父母 p 是否有一个未命名的孩子:'abc'

========== 已编辑:

我个人不喜欢这个查询,因为它正在收集 x2 然后稍后展开。但为了回答 SO 问题,

Match (x1:Parent) with x1 
optional Match (x1)-[:CHILD]->(x2:Child) with x1 , collect({x1:x1, x2:x2}) as x3 
UNWIND x3 as x2 
WITH x2.x1 as x1, x2.x2 as x2, x3 
where NOT x2.name IN ['abc'] OR x2 is NULL 
RETURN distinct x1

我收集了 x1 和 x2,然后通过在展开期间获取 x1 和 x2 来展开集合。这将包括没有 x2(没有 CHILD)的其他节点。我还简化了 where 条件,因为 x2 也可以访问,而不是在 x3 上再次循环


推荐阅读