12
votes

Single relationships can be excluded by types using

Match (n:Person)-[r]-(m:Person) where type(r)<>"FRIENDS" return n,r,m

Is there a way to exclude multilevel relationships with cypher?

Match (n:Person)-[r*2..4]-(h:Hobby) where type(r)<>"FRIENDS" return n,r,h
2

2 Answers

19
votes

Sure, you can do that. Like this:

Match (n:Person)-[r*2..4]-(h:Hobby) 
where NONE( rel in r WHERE type(rel)="FRIENDS") 
return n,r,h

Your query doesn't work because with multi-level paths, your r is a collection of relationships rather than a single one. So you can use any of the predicates on collections to do the filtering that you want.

Here, I chose NONE with type(rel)=FRIENDS, which means that you'll only get the result back if NONE of the relationships are of type FRIENDS. But you might instead want to use ANY or ALL, depending on what your query is supposed to mean.

Anyway, the main point here is to use a predicate function to turn a collection of things into a single boolean value.

5
votes

You can use the ALL or ANY predicates for this:

MATCH p=(n:Person)-[*2..4]-(h:Hobby) 
WHERE ALL(x in relationships(p) WHERE type(x) <> "FRIENDS")
RETURN n,r,h

Use the ALL predicate to make sure every relationship along that path is not a FRIEND. Use ANY to make sure you have at least one relationship not being FRIEND.