doyle
doyle

Reputation: 63

How to match all possible paths through multiple relationship types with filtering (Neo4j, Cypher)

I am new to Neo4j and I have a relatively complex (but small) database which I have simplified to the following: room/door/window example

The first door has no key, all other doors have keys, the window doesn't require a key. The idea is that if a person has key:'A', I want to see all possible paths they could take.

Here is the code to generate the db

CREATE (r1:room {name:'room1'})-[:DOOR]->(r2:room {name:'room2'})-[:DOOR {key:'A'}]->(r3:room {name:'room3'})
CREATE (r2)-[:DOOR {key:'B'}]->(r4:room {name:'room4'})-[:DOOR {key:'A'}]->(r5:room {name:'room5'})
CREATE (r4)-[:DOOR {key:'C'}]->(r6:room {name:'room6'})
CREATE (r2)-[:WINDOW]->(r4)

Here is the query I have tried, expecting it to return everything except for room6, instead I have an error which means I really don't know how to construct the query.

with {key:'A'} as params
match (n:room {name:'room1'})-[r:DOOR*:WINDOW*]->(m)
where r.key=params.key or not exists(r.key)
return n,m

To be clear, I don't need my query debugged so much as help understanding how to write it correctly.

Thanks!

Upvotes: 0

Views: 54

Answers (1)

cybersam
cybersam

Reputation: 66957

This should work for you:

WITH  {key:'A'} AS params
MATCH p=(n:room {name:'room1'})-[:DOOR|WINDOW*]->(m)
WHERE ALL(r IN RELATIONSHIPS(p) WHERE NOT EXISTS(r.key) OR r.key=params.key)
RETURN n, m

With your sample data, the result is:

╒════════════════╤════════════════╕
│"n"             │"m"             │
╞════════════════╪════════════════╡
│{"name":"room1"}│{"name":"room2"}│
├────────────────┼────────────────┤
│{"name":"room1"}│{"name":"room3"}│
├────────────────┼────────────────┤
│{"name":"room1"}│{"name":"room4"}│
├────────────────┼────────────────┤
│{"name":"room1"}│{"name":"room5"}│
└────────────────┴────────────────┘

Upvotes: 1

Related Questions