Reputation: 20150
Suppose I have nodes that can be joined by a set of pattern of paths, for example:
(x:Class {code:'xxx'})<-[:a]-()-[:b]->()<-[:a]-()-[:b]->()<-[:a]-()-[:b]->()<-[:a]-()-[:b]->(y:Class{code:'yyy'})
There can be a variable number of <-[:a]-()-[:b]->
between x
and y
. How can I get the shortest path if it exist between x
and y
?
Upvotes: 3
Views: 433
Reputation: 30397
As mentioned in the comments, the path expander procs from APOC Procedures provide a way to handle repeating sequences.
However it looks like you're not just looking for a specific end node, but for one that occurs at that point in the sequence (and not, say, as the node in the middle of those relationship pairs).
In that case we need to include the labelFilter too, to specific which node in the sequence we're interested in. Or we can just use the sequence
config parameter instead of both the label and relationship filters.
MATCH (start:Class {code:'xxx'}), (end:Class{code:'yyy'})
CALL apoc.path.expandConfig(start, {endNodes:[end], sequence:'>Class, <a, *, b>', limit:1}) YIELD path
RETURN path
We supply the end nodes we're interested in (since we already know those, we matched to them already), then we supply the sequence of alternating node labels and relationship types (using *
as a standin for a node of any label, and using a prefix of >
as an end node filter, meaning we want paths that end at this :Class node in this position of the sequence).
The path expander procs use breadth-first expansion, and the limit:1
means the first path we encounter to a node that is both an end node, and that satisfies the sequence pattern (a :Class node at that point in the repeating sequence) will be our shortest path.
Upvotes: 2