Search code examples
neo4jcypher

neo4j, how to query chain using two different nodes


I have a neo4j graph: (person)-[like]-(fruit). I want to find person of person of person recursively using [like] and (fruit).

For example,

(John)-[like]->(Apple)<-[like]-(Sam)->[like]-(Banana)<-[like]-(Jack)-[like]->(Grape)<-[like]-(Lisa)...

How can I query this relationship using the neo4j?


Solution

  • If the sequence in your path is always a repetition of person, fruit, person ... and assuming only people like fruit and not the other way round, you could use a quantified path pattern like this:

    MATCH p = ((:Person)-[:like]->(:Fruit)<-[:like]-(:Person))+
    RETURN p
    

    If you want the paths to start at a particular person e.g. 'John', anchor the start node like so:

    MATCH p = (:Person {name: 'John'}) 
              ((:Person)-[:like]->(:Fruit)<-[:like]-(:Person))+
    RETURN p
    

    If you want to include paths where only one person likes a fruit, use a UNION:

    MATCH p = ((:Person)-[:like]->(:Fruit)<-[:like]-(:Person))+
    RETURN p
    UNION
    MATCH p = (:Person)-[:like]->(:Fruit) 
    RETURN p
    

    Note that some results may be subpaths of other results.

    If you are using a version < 5.9 and have APOC installed, you can specify a sequence of labels and relationship types in the configuration of apoc.path.expandConfig. This returns paths that start at 'John':

    MATCH (p:Person {name: 'John'})
    CALL apoc.path.expandConfig(p, {
        sequence: 'Person, like>, Fruit, <like, >Person'
    })
    YIELD path
    RETURN path