Variable path ordering

I have a relationship that is basically a linear parentage chain. A node can only have a single incoming relationship of this type. This can be arbitrarily deep, but reasonably doesn't get deeper than ~10.

example data
(a:Asset {id:1})-[:PART]->(b:Asset {id:2})->[:PART]->(c:Asset {id:3})-[:PART]->(d:Asset {id:4})...

Given any node, I need to be able to return it's lineage all the way up to the top. However I need it to be ordered.

This query does the trick well:

MATCH (:Asset {id: '3'})<-[:PART*0..20]-(a:Asset)

This returns me:

What I'm wondering is the order of this response guaranteed to be visit order?
Empirically I cannot find a result that is out of order, but I want to make sure that order is stable or find a different way to ensure the stable order.

Thanks in advance

I've now found scenarios where this does not come back ordered.

Any suggestions on how to get this ordered by traversal path?

The best I can come up with is this, which doesn't seem ideal:

MATCH p=(root:Asset {id: '3'})<-[:PART*0..20]-(a:Asset) 
UNWIND nodes(p) as a

Is there a better way?

Variable-length path matches should be using dfs, so for the examples provided your initial query should work just fine.

What may be throwing off your results for other kinds of queries is which node the planner uses to lookup as a starting node, since the results you would see would be depth-first from the starting node. Depending on the indexes available, it could be that you don't have an index that can be used for your desired starting node, or maybe in your pattern there are multiple places where an index lookup could be used, and the planner may not be choosing the one you want.

You can use EXPLAIN or PROFILE to see a plan of how the planner will execute the query, which you can use to see which node will be the starting node for the expansion.

If it's not what you expect, or if you need to use this in other scenarios and need to enforce which node is the starting node, you can use an index hint (provided you have created an index for the label/property) to force the planner to start there.