Reputation: 954
I am trying to find the shortest path between two nodes but I need to exclude some nodes from the path. The cypher that I am trying is
START a=node(1), b=node(2), c=node(3,4)
MATCH p=a-[rel:RELATIONSHIP*]-b
WHERE NOT (c in nodes(p))
RETURN p
ORDER BY length(p) LIMIT 1
But this is giving me a path which includes one of the nodes in c.
Is there a way to do a traversal excluding some nodes?
Thanks
Upvotes: 1
Views: 1679
Reputation: 9952
The MATCH ... WHERE
part should be fine, but your START
clause may not do what you expect. Do the following and consider the result
START a=node(1), b=node(2), c=node(3,4)
RETURN ID(a), ID(b), ID(c)
You get back
==> +-----------------------+
==> | ID(a) | ID(b) | ID(c) |
==> +-----------------------+
==> | 1 | 2 | 3 |
==> | 1 | 2 | 4 |
==> +-----------------------+
That means the rest of the query is executed twice, once excluding (3)
from the path and once excluding (4)
. But that also means of course that it is run once not excluding each of them, which means you can indeed get results with those nodes present on the path.
If you want to exclude both of those nodes from the path, try collecting them and filtering with NONE
or NOT ANY
or similar. I think something like this should do it (can't test at the moment).
START a=node(1), b=node(2), c=node(3,4)
WITH a, b, collect (c) as cc
MATCH p=a-[rel:RELATIONSHIP*]-b
WHERE NONE (n IN nodes(p) WHERE n IN cc)
RETURN p
ORDER BY length(p) LIMIT 1
Upvotes: 3