neo4jcypher

MATCH with optional graph parts


I have a graph model consisting of two node types. Each USER has a dependency to one or more USERs via a DEPDATA node (which holds significant information on the relationship).

(:USER)-[:DEPENDS_ON]->(:DEPDATA)-[:FOR]->(:USER)

This chain can have infinite length, so the part

-[:DEPENDS_ON]->(:DEPDATA)-[:FOR]->(:USER)

can be repeated n times. It's also possible that a USER has no relationships, so this all is valid

(:USER)
(:USER)-[:DEPENDS_ON]->(:DEPDATA)-[:FOR]->(:USER)-[:DEPENDS_ON]->(:DEPDATA)-[:FOR]->(:USER)

What I like to retrieve is all USER nodes which depend on a specific USER node, regardless in which depth.

I've already read about variable relationship length here http://graphaware.com/graphaware/2015/05/19/neo4j-cypher-variable-length-relationships-by-example.html but it seems to apply only for direct relations.

How can I make a whole part of the graph structure to be matched 0..n times?


Solution

  • You're using n as your upper bound, but you said the chain could be infinite length. In this situation, if you are not applying an upper bound, then you don't need to have a variable for it.

    I think what you're looking for is something like this (using ID property as a placeholder for however you're uniquely identifying the dependent User node):

    MATCH (dep:User{ID:123})<-[:DEPENDS_ON|FOR*0..]-(u:User)
    RETURN DISTINCT u
    

    This will match on zero or more chains of :DEPENDS_ON or :FOR relationships, finding all distinct dependent users.