cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Cypher select vertices whose any neighbours do not contain a property

3X_4_a_4a8030d2e5cddd1125fcef30c6b993f73c5a475b.png

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

Neo4j 4.1

1 REPLY 1

Using this graph:

create (p1:Person {name: "p1"})
create (p2:Person {name: "p2"})
create (p3:Person {name: "p3"})
create (p4:Person {name: "abc"})
create (p5:Person {name: "p5"})
create (p6:Person {name: "p6"})
create (p7:Person {name: "p7"})
create (p8:Person {name: "p8"})

MERGE (p1)-[:CHILD]->(p2)
MERGE (p1)-[:CHILD]->(p3)

MERGE (p4)-[:CHILD]->(p5)
MERGE (p4)-[:CHILD]->(p6)
MERGE (p7)-[:CHILD]->(p5)
MERGE (p7)-[:CHILD]->(p6)

How about:

match (p1)<-[:CHILD]-(child)-[:CHILD]->(p2)
WHERE id(p1) < id(p2)
WITH p1, p2, collect(child) AS children
WHERE none(child in children WHERE child.name = "abc")
return p1.name, p2.name, [child in children | child.name]