Return node if relationship is not present

Solution 1:

Update 01/10/2013:

Came across this in the Neo4j 2.0 reference:

Try not to use optional relationships. Above all,

don’t use them like this:

MATCH a-[r?:LOVES]->() WHERE r IS NULL where you just make sure that they don’t exist.

Instead do this like so:

MATCH a WHERE NOT (a)-[:LOVES]->()

Using cypher for checking if relationship doesn't exist:

...
MATCH source-[r?:someType]-target
WHERE r is null
RETURN source

The ? mark makes the relationship optional.

OR

In neo4j 2 do:

...
OPTIONAL MATCH source-[r:someType]-target
WHERE r is null
RETURN source

Now you can check for non-existing (null) relationship.

Solution 2:

For fetching nodes with not any relationship

This is the good option to check relationship is exist or not

MATCH (player)
    WHERE NOT(player)-[:played]->()
    RETURN player

You can also check multiple conditions for this It will return all nodes, which not having "played" Or "notPlayed" Relationship.

MATCH (player) 
 WHERE NOT (player)-[:played|notPlayed]->()
 RETURN player

To fetch nodes which not having any realtionship

MATCH (player) 
WHERE NOT (player)-[r]-()
RETURN player

It will check node not having any incoming/outgoing relationship.

Solution 3:

If you need "conditional exclude" semantic, you can achieve it this way.

As of neo4j 2.2.1, you can use OPTIONAL MATCH clause and filter out the unmatched(NULL) nodes.

It is also important to use WITH clause between the OPTIONAL MATCH and WHERE clauses, so that the first WHERE defines a condition for the optional match and the second WHERE behaves like a filter.

Assuming we have 2 types of nodes: Person and Communication. If I want to get all Persons which have never communicated by the telephone, but may have communicated other ways, I would make this query:

MATCH (p: Person) 
OPTIONAL MATCH p--(c: Communication) 
WHERE c.way = 'telephone'
WITH p, c 
WHERE c IS NULL 
RETURN p

The match pattern will match all Persons with their communications where c will be NULL for non-telephone Communications. Then the filter(WHERE after WITH) will filter out telephone Communications leaving all others.

References:

http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional