Given a simple graph with 3 user nodes and 2 company nodes, that can be created in a sandbox with the following cypher. Each user has a role with property "employee=true" on his own company and can can have more roles on other companies with "employee=false". In this sample, only John have such an additional role for his client.
create (u:User { name:"John"})-[:HAS_ROLE {employee:true}]->(c:Company { name:"XYZ Consultants"});
match (c:Company { name:"XYZ Consultants"}) merge (u:User { name:"Jane"})-[:HAS_ROLE {employee:true}]->(c);
create (u:User { name:"Frank"})-[:HAS_ROLE {employee:true}]->(c:Company { name:"XYZ Client"});
match (c:Company { name:"XYZ Client"}) match (u:User { name:"John"}) merge (u)-[:HAS_ROLE {employee:false}]->(c);
Result looks like this:
Now I want to query all users who have roles for companies John has roles for, including their employer (that role with employee=true). Expecting to get all 3 users together with their companies with the following cypher:
MATCH (me:User {name:"John"})-[:HAS_ROLE]->(company:Company)
MATCH (company)<-[userHasRole:HAS_ROLE]-(u:User)-[:HAS_ROLE {employee:true}]->(employer:Company)
return u, employer
But this cypher only returns John.
Splitting the last MATCH into two statements, it returns the expected result of Frank, Jane and John:
MATCH (me:User {name:"John"})-[:HAS_ROLE]->(company:Company)
MATCH (company)<-[userHasRole:HAS_ROLE]-(u:User)
MATCH (u)-[:HAS_ROLE {employee:true}]->(employer:Company)
return u, employer
I would have expected both cyphers to return the same result as nothing is optional.
It gets even more interesting when putting it together into one line, in that case, nothing is returned.
MATCH (me:User {name:"John"})-[:HAS_ROLE]->(company:Company)<-[userHasRole:HAS_ROLE]-(u:User)-[:HAS_ROLE {employee:true}]->(employer:Company)
return u, employer
It looks like the same relation isn't traversed again within the same match statement? But is this an intended behaviour??
Did I miss something?
Best,
Reiner