# Varliable length path with "path pattern" best practice

Hi there,
in cypher one can query variable length path through (b)-[:Reltype*]->(b) pattern
FOAF is a good example for that.

Now assume i have the following graph

i could search the varables and related function with patterns like
(x:Variable)-[i:in]->(f:F)-[o:out]->(y:Variable)

i can distingish between inputs outputs Functions and Variables (important)
this would kind of represent the following mathematical term.

Y=F(X)
with
X being a vector with x1,...,xn
Y being a vector with y1,....yn

well now one could have
Xn=Fn(Fn-1(Fn-2(....F0(X)...)))

in other words the result of a function is the input of an other function

how can i query all functions and intermediate variables for a specific output value?
(a:Variable)-[:in*]->(f:Funciton) .... would not work
i need something like ((i:Variable)-[:in]-(f:Function)-[:out]->(o:Variable))[0...*]

in this example relation and node filters on path extension (apoc) would be sufficient. But there are other graphs where label and relation filters are not sufficient. The order of relations would be important.

regards
Thomas

the order of relationships would be important
To clarify: Are you're requiring that after each `in` relationship there needs to be a `out` relationship. So two subsequent `in` would not be a valid pattern?
If that is your requirement, take a look at sequences for `apoc.path.expandConfig` at https://neo4j.com/docs/labs/apoc/current/graph-querying/path-expander/#_sequences.

Hi Stefan,
yes the sequence is important
a sequence would be this example
(V)-[in]->(F)-[out]->(V)-[in]->(F)-[out]->(V)-[in]->(F)-[out]-(V)
the graph might have other relations/paths that i do not care of.

I words, search all paths that

2. as iinput (in) for a Funktion (F)
3. having an output (out) Variable (V) (recurse to 1 or return this path)

`beginSequenceAtStart:false, sequence:'V,in>, F, out>,V`

would be
`match (x1:Variable) where x1..name="x1"`
`call apoc.path.expandConfig(x1,{sequence:"V,in>, F, out>,V"}) yield path as p return p`

return
x1-F1-y1
x2-F1-y2
x1-F1-y1-F2-y4
x1-F1-y2-F3-y5
x1-F1-y2-F3-y6
x1-F1-y3-F3-y5
x1-F1-y3-F3-y6

?

regards
Thomas

Close, just remember that the sequence repeats, so you don't need the V at the end, since it's at the start: `sequence:'V, in>, F, out>'`

If you want this to only return paths that end at `V` nodes, then you can use an end node label filter symbol `>` before the `V`: `sequence:'>V, in>, F, out>'`

Also `beginSequenceAtStart:false` changes the behavior and ordering of the sequence: the starting element is a relationship (which will not be a part of the subsequent sequence, it only gets us to the start of the sequence), but the ending element is still a relationship. For example, if the start node wasn't a :V node, but some other node, and wasn't important in the sequence, we could use:

`beginSequenceAtStart:false, sequence:'in>, F, out>, >V, in>'`

And likewise if the first relationship to the start of a sequence isn't in the sequence. Let's say you had a :begin relationship from the start node to the sequence, then you would use:

`beginSequenceAtStart:false, sequence:'begin>, F, out>, >V, in>'`
As noted, the first relationship here isn't really the start of the sequence, but gets us one hop away to the sequence's real start.

2 Likes

Hi Stefan, Andrew,
i appreciate your help. This makes a whole category of problems much easier to takle.

I tested and i am very happy with it. 