Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting a list of nodes through multiple path addresses in Cypher

Tags:

neo4j

cypher

Consider following Cyphers:

MATCH (n{name: "John"})-[:Colleague]-(m) RETURN m;

This query finds Colleague(s) of John(s). Now another one:

MATCH (n{name: "John"})-[:Friend]-()-[:Colleague]-(m) RETURN m;

This one finds Colleague(s) of John(s)' Friend(s). And now the last one:

MATCH (n{name: "John"})-[:Colleague]-()-[:Friend]-(m) RETURN m;

Finally, this one finds Friend(s) of John(s)' Colleague(s). What I'm looking for is a Cypher query which finds the union of all of the nodes found by the given queries.

Please note that this is just an example. What I'm actually asking here is how to find one set of nodes using multiple paths? Something like:

MATCH (n{name: "John"})
    -[:Colleague]- /
    -[:Friend]-()-[:Colleague]- /
    -[:Colleague]-()-[:Friend]-
    (m) RETURN m;
like image 783
Mehran Avatar asked Dec 06 '25 17:12

Mehran


1 Answers

In this particular case, you can use a variable-length relationship with multiple relationship types. However, to prevent bad paths (colleague of colleague, friend of friend, and just friends) we have to do some additional filtering to ensure that there is at least one colleague relationship in the path.

MATCH (n{name: "John"})-[r:Colleague|Friend*1..2]-(m) 
WHERE 'Colleague' in [rel in r | type(rel)]
RETURN m;

Also, I highly recommend that you use a label on your nodes, and use an index on the label / name combination so your lookup to your John node is fast, instead of having to check every single node in your graph.

This query won't be as performant as queries doing a UNION, but with an index lookup and only two traversals, with not too many relationships, it should work fine.

like image 66
InverseFalcon Avatar answered Dec 09 '25 22:12

InverseFalcon