0
votes

I want all path between A:Alpha and D:Alpha with only :Beta nodes between these two. If path contains same type or other type of node then those path should discarded.

Sample data - 
A:Alpha->B:Beta->C:Beta->D:Alpha
A:Alpha->M:Beta->Z:Gama->P:Beta->D:Alpha
A:Alpha->S:Beta->F:Beta->I:Beta-->D:Alpha
A:Alpha->U:Beta->X:Alpha->T:Alpha->W:Beta->D:Alpha

Result should be - 
A:Alpha->B:Beta->C:Beta->D:Alpha
A:Alpha->S:Beta->F:Beta->I:Beta-->D:Alpha

Can any one help me with cypher for the same.

Thanks

1

1 Answers

1
votes

You just need a variable-length path and a WHERE all() predicate to restrict the labels of the middle nodes of the path:

... // assume 'path' variable used in the match
WHERE all(node in nodes(path)[1..-1] WHERE node:Beta)
...

Alternately, you can use APOC Procedures, as the options for the path expander should be able to deliver what you want:

MATCH (a:Alpha)
CALL apoc.path.expandConfig(a, {relationshipFilter: '>', labelFilter:'/Alpha|+Beta' filterStartNode:false}) YIELD path
RETURN path

The label filter is the key here. /Alpha creates a termination node filter on :Alpha nodes, meaning that paths will be traversed only up to the first :Alpha node encountered and not beyond, and the paths returned will always end with an Alpha node. +Beta creates a whitelist filter on :Beta nodes for nodes in the path (which doesn't apply to the end node when we use a termination filter), and the filterStartNode:false means the start node isn't subject to the whitelist filter either.

This ensures that paths only go to the first :Alpha node, and all middle nodes in the path must be :Beta nodes.