I have the following query:
MATCH path=(p)<-[r:partOf*0..]-(a:Node)
WHERE elementId(a) = '<some parameter>'
WITH a, COLLECT (p.body) AS ancestors
RETURN
a.someattributes AS attributes,
a.body AS body,
ancestors
the body attribute of each of the nodes is a JSON file, making my query I get:
[ "{ json body reference }", "{ json parent reference }", "{ json grand parent reference }", "{ json great grand parent reference }", "{ json root reference }"]
is it guaranteed that the list is always returned ordered?
@joshcornejo
if you want guarenteed order your need to use a ORDER BY
clause.
Without it, It may be ordered today but given no ORDER BY
clause, if you upgrade it may or may not still maintain order
Sorry, i don't get it?
(a {body:'{son}'})-[:partOf]->(b {body:'{dad}'})-[:partOf]->(c {body:'{granddad}'})-[:partOf]-(d {body:'{greatgp}'})
the list of the body property comes inside the COLLECT (p.body) and there is no attribute to order, other than the fact that there is the [:partOf] relationship which defines the hierarchy, which isn't necessarily chronologically meaningful (this is a linear example, but the ancestry could be a graph and I could associate some today, some other tomorrow in any sequence).
the ancestors that contains 'body' list has [ {son}, {dad}, {granddad}, {greatgp} ] which are in the right order, but I don't know if the path/collect combination provides the guaranteed order.
If you are referring to the order of your ancestors list, it has been my experience that a variable length will return the list in the same order. It is not guaranteed as @dana_canzano stated. You could approach it differently so you get back a list in the same order. Instead of getting a list of paths back with increasing length until the end is reached, then collecting the end node of each path, you could get one path path that represents the longest path and get the nodes along the path. It is my experience the collection of nodes in this case will be ordered by their position along the path.
MATCH path=(p)<-[r:partOf*0..]-(a:Node)
WHERE elementId(a) = '<some parameter>'
AND not exists(()<-[r:partOf]-(p))
WITH a, [i in nodes(path) | i.body] AS ancestors
RETURN
a.someattributes AS attributes,
a.body AS body,
ancestors
If your body attribute contains json objects as a string, you can convert them to neo4j maps
for the 4 node hiearchy, this new way returns 4 rows
<a's attributes> [ {son} ]
<a's attributes> [ {son}, {father} ]
... i only need (and from my query already get):
<a's attributes> [ {son}, {dad}, {grandad}, {greatgp}]
and to know that the list of bodies is always ordered from leaf to root
You should only get one row if only one path originates from ‘a’. The cause must be my oversight, as I cut and pasted and didn’t pay attention to the variable ‘r’ bound to the relationship.
Try this.
MATCH path=(p)<-[r:partOf*0..]-(a:Node)
WHERE elementId(a) = '<some parameter>'
AND not exists(()<-[:partOf]-(p))
WITH a, [i in nodes(path) | i.body] AS ancestors
RETURN
a.someattributes AS attributes,
a.body AS body,
ancestors
My experience is that the results returned from a variable length search will be in the order of length. That being said you should not rely on that as it is implementation dependent and neo4j can change that at anytime.
If you want to ensure the order, you can order by path length before collecting.
MATCH path=(p)<-[r:partOf*0..]-(a:Node)
WHERE elementId(a) = '<some parameter>'
WITH a, p, path
ORDER BY length(path)
WITH a, COLLECT (p.body) AS ancestors
RETURN
a.someattributes AS attributes,
a.body AS body,
ancestors
1 Like