0
votes

How do I return just the portion of a variable length pattern path that meets some criteria?

In the example below, the following cypher query will return both blue & red nodes.

MATCH p=(a:Person)-[:KNOWS*1..10]->(b:Person)-[:KNOWS]->(j:Person { name: 'Jane'})
RETURN p

enter image description here

However, I want to return the blue nodes that have an incoming relationship confidence_factor >= 0.75. The issue is that everything I've tried either

  1. Eliminates the entire upper mixed blue/red path b/c it's got one rel that fails test
  2. Eliminates just the Jim->Erin rel b/c it fails the test.

Effectively, I want all sequential nodes going backwards from Jane where relationship confidence_factor >= 0.75 but a given path should stop as soon as it encounters a rel that fails that test, and NOT CONTINUE, even if other relationships between nodes in that path might pass (e.g. Tom-[:KNOWS]->Jim)

CREATE (one:Person { name: 'Tom'})
,(two:Person { name: 'Jim'})
,(three:Person { name: 'Erin'})
,(four:Person { name: 'Kevin'})
,(five:Person { name: 'Skylar'})
,(six:Person { name: 'Jane'})

,(one)-[:KNOWS {confidence_factor:0.80}]->(two)
,(two)-[:KNOWS {confidence_factor:0.05}]->(three)
,(three)-[:KNOWS {confidence_factor:0.85}]->(six)
,(four)-[:KNOWS {confidence_factor:0.90}]->(five)
,(five)-[:KNOWS {confidence_factor:0.95}]->(six)
;
1

1 Answers

0
votes

You should already get multiple rows with different path lengths. Just look for those paths where all relationships match your criteria.

MATCH p = (:Person {name: 'Jane'})<-[:KNOWS*1..10]-(:Person)
WHERE all(r IN relationships(p) WHERE r.confidence_factor >= 0.75)
RETURN p

If you want to extract the nodes from the path without Jane (remove tail() if you want Jane to be included):

MATCH p = (:Person { name: 'Jane'})<-[:KNOWS*1..10]-(:Person)
WHERE all(r IN relationships(p) WHERE r.confidence_factor >= 0.75)
UNWIND tail(nodes(p)) as person
RETURN DISTINCT person