neo4jcypher

Matching variable length paths in Neo4j with WHERE


I am getting my head around a Neo4j database that links people together, along with details of how they are connected.

Specifically I have a "Person" node and a "KNOWS" relationship which has a "met_at" property.

I can now match a variable length path with:

MATCH (:Person {name:'A'})-[r:KNOWS*1..5]->(:Person {name:'B'}) RETURN r

to get links between people. So far so good.

Now imagine I have the following connections:

Is it possible to craft a WHERE to add to the above MATCH statement so that when finding paths from A to F it excludes the path A->B->D->E->F because B met D at the same time as D met E ... ie. it only returns A->C->E->F

I know I could do each level separately:

MATCH (:Person {name:'A'})-[r1:KNOWS]->(:Person)-[r2:KNOWS]->(:Person {name:'F'}) WHERE r2.met_at <> r1.met_at RETURN r1,r2
MATCH (:Person {name:'A'})-[r1:KNOWS]->(:Person)-[r2:KNOWS]->(:Person)-[r3:KNOWS]->(:Person {name:'F'}) WHERE r2.met_at <> r1.met_at AND r3.met_at <> r2.met_at RETURN r1,r2,r3
etc...

but I am trying to do it in a single query, is that possible?

Thanks :-)


Solution

  • If you want to find all KNOWS paths (up to length 5) from A to F in which adjacent nodes do not have the same met_at value, you can do this:

    MATCH p = (:Person {name:'A'})-[r:KNOWS*1..5]->(:Person {name:'F'})
    WHERE ALL(i IN RANGE(0, LENGTH(p) - 2) WHERE 
      r[i].met_at <> r[i+1].met_at)
    RETURN p