Is it possible to filter returned relationships by their properties?

Hello! I was hoping that I could solve a problem of extracting one of many possible paths out of neo4j but I'm starting to think this isn't possible. I'd really appreciate any help/pointers.

Goal

We have a few "Place" nodes constructed in the test data below. "People" visit "Place"s one at a time and in doing so, create a parent-child relationship between the places. Each person will have a different path through the places. I want to extract each person's path separately.

Example

Set up some data

with [{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 }] as nodes
unwind nodes as node
create (p:Place) set p += node;
match (one {id: 1}) 
match (two {id: 2})
match (three {id: 3})
match (four { id: 4 })
match (five { id: 5})
merge (one)<-[:follows { person: 1 }]-(two)
merge (two)<-[:follows { person: 1 }]-(four)
merge (four)<-[:follows { person: 1 }]-(three)
merge (three)<-[:follows { person: 1 }]-(five)
merge (one)<-[:follows { person: 2 }]-(two)
merge (two)<-[:follows { person: 2 }]-(three)
merge (three)<-[:follows { person: 2 }]-(four)
merge (four)<-[:follows { person: 2 }]-(five)

With the following query, I'm expecting edges to not be returned if they have a person property that is not 1. This doesn't happen - all edges are returned between the matching nodes.

match (tail:Place)
where not exists {
 match (tail)<-[:follows {person: 1}]-()
}
with tail
match p=(tail)-[*1..2 { person: 1 }]-()
return p

Is this possible?

Hi @neverstew,

You can try using two hops as in the query below:

match (tail:Place)
where not exists {
match (tail)<-[:follows {person: 1}]-()
}
with tail
MATCH p=(tail)-[{ person: 1 }]-()-[{ person: 1 }]-()
return p

Hope this helps

I you are viewing the results in Desktop and looking at the graph, you will see all relationships between the matching nodes. In your case, it shows edges with 'person: 2' attribute. Instead, look at the 'Table' or "Text' views. These show the results of your query. You will notice that your results in these two views only contains edges with 'person: 1' attribute. The following is the 'text' view result.

Just a note, you could simplify your data creation script with the following:

unwind range(1,5) as index
create (p:Place) set p.id=index

1 Like

Thanks for this very helpful answer, @glilienfield . You're right, the query does what I expected though the browser was throwing me off.

that is great...glad to help. Also, you can simplify your query, unless you have a specific reason for its structure:

match p=(tail:Place)-[*1..2 { person: 1 }]-()
where not exists {
match (tail)<-[:follows {person: 1}]-()
}
return p