James Newton
James Newton

Reputation: 7082

Using Neo4j Cypher to find which nodes are not related to each other

In Neo4j, I create a small graph with 4 nodes, some of which are linked to some others:

CREATE
(a:Room {name:"A"})
-[:DOOR]->
(b:Room {name:"B"})
-[:DOOR]->
(c:Room {name:"C"})
-[:DOOR]->
(d:Room {name:"D"}),
a-[:DOOR]->c,
a-[:DOOR]->d,
b-[:DOOR]->a
RETURN a,b,c,d

enter image description here

I want to find which rooms do not have a door between them. I'm hoping for an output something like this:

{"B": ["D"], "C": ["A", "B"], "D": ["A", "B", "C"]}

I can do this for one given starting point...

MATCH (b), (r)
WHERE b.name = "B"
AND NOT (b)-[:DOOR]->(r)
AND b <> r
RETURN r
// Returns Room D

Here's my cargo-cult pseudo code for iterating through each possible pair of nodes:

MATCH rooms = (r)
SET output = {}
FOREACH (
room IN nodes(rooms),
exit IN nodes(rooms),
missing = [],
output[room.name] = missing
|
IF room <> exit AND NOT room-[:DOOR]->(exit)
THEN missing = missing + exit
)
RETURN output

Please help me to understand how to formulate this correctly in Cypher.

Upvotes: 1

Views: 1001

Answers (1)

jjaderberg
jjaderberg

Reputation: 9952

The WHERE clause takes relationship patterns and you can use the NOT function to filter on the absence of a relationship.

MATCH (a:Room), (b:Room)
WHERE NOT a-[:DOOR]-b AND a <> b
RETURN a, b

Here's the section in the docs.

Upvotes: 3

Related Questions