1
votes

I have a following graph in Neo4j

(id:5,t:e)<--(id:4,t:w)<--(id:0;t:s)-->(id:1,t:w)-->(id:2,t:b)-->(id:3,t:e)

now I search paths from nodes with t:s to nodes with t:e such that only white-listed nodes with t:w are in-between.

So ideally i need a query to return only (0)-->(4)-->(5) but not (0)-->(1)-->(2)-->(3).

EDIT: i have forgotten to mention that paths may have variable length: from 0 to potentially infinity. It means that I may have an arbitrary number of "t:w" nodes

Best regards

1

1 Answers

1
votes

Working just with the information that you have provided above you could use

MATCH p=({t:'s'})-->({t:'w'})-->({t:'e'}) RETURN p

Of course if an s could link directly to an e you will need to use variable length relationships matches.

MATCH p=({t:'s'})-[*0..1]->({t:'w'})-[]->({t:'e'})
RETURN DISTINCT p

EDIT - Paths of any length

MATCH p=({t:'s'})-[*0..1]->({t:'w'})-[*]->({t:'e'})
RETURN DISTINCT p

To match a path of any length use the * operator in the relationship path match. It is usually best to put some bounds on that match, an example of which is the *0..1 (length 0 to 1). You can leave either end open *..6 (length 1 to 6) or *2.. (length 2 to whatever).

The problem with this is that now you cannot guarantee the node types in the intervening nodes (so t:"b" will be matched). To avoid that I think you'll have to filter.

MATCH p=({t:'s'})-[*]->({t:'e'})
WHERE ALL (node IN NODES(p)
   WHERE node.t = 's' OR node.t = 'w' OR node.t = 'e' )
RETURN p

End Edit

You should introduce labels to your nodes and use relationship types for traversal though as that is where Neo/Cypher is going to be able to help you out. You should also make sure that if you are matching on properties that they are indexed correctly.