Cypher select vertices whose any neighbours do not contain a property

Viewed 76

enter image description here

{
    "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"
    }
}

I want to select the Parents which do not have any child with name='abc'

Expected Behaviour : I should get both Parents (foo1 and foo2) as result

Query1 :

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 

This query is returning me only 1 Parent(foo1) but it should return both parents and 2nd parent(foo2) is not connected to any child.

PS : Reason for using UNWIND is to use the variables for further WHERE clauses on variable x2.

1 Answers

This will get all Parents without a child name: 'abc' or without any child

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

Check if the given parent, p has a child not named: 'abc'

========== EDITED:

Personally I dislike this query because it is collecting x2 then unwinding it later. But for sake of answering the SO question,

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

I collected BOTH x1 and x2 then UNWIND the collection by getting x1 and x2 during unwind. This will include other nodes that has no x2 (without a CHILD). I also simplified the where condition because x2 is also accessible rather than looping again on x3

Related