rorymadden
rorymadden

Reputation: 954

Neo4j Graph Traversal excluding nodes

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

Answers (1)

jjaderberg
jjaderberg

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

Related Questions