图表要点:http://gist.neo4j.org/?6182d024325343760cb4
我想按顺序获得一条(最长的)路径,它按预期工作,直到我添加一个COLLECT语句,是否有一些关于Cypher和COLLECT的东西,我只是不明白或者这是一个错误?
此查询按预期工作,以正确的顺序返回路径中的节点:
MATCH (n:Cable { name: 'Cable3' })-[:Connected_to*]-(port:Port)
OPTIONAL MATCH path=(port)-[:Connected_to*]-()
WITH nodes(path) AS parts, length(path) AS len
ORDER BY len DESC
LIMIT 1 UNWIND parts AS part
RETURN part
这一个没有COLLECT语句,以正确的顺序返回节点,但也返回部分和父节点之间的节点(如预期的那样)。
MATCH (n:Cable { name: 'Cable3' })-[:Connected_to*]-(port:Port)
OPTIONAL MATCH path=(port)-[:Connected_to*]-()
WITH nodes(path) AS parts, length(path) AS len
ORDER BY len DESC
LIMIT 1 UNWIND parts AS part
OPTIONAL MATCH (part)<-[:Has*1..10]-(parent)
RETURN part, parent
此查询无法按预期工作,以其他顺序返回路径中的节点:
MATCH (n:Cable { name: 'Cable3' })-[:Connected_to*]-(port:Port)
OPTIONAL MATCH path=(port)-[:Connected_to*]-()
WITH nodes(path) AS parts, length(path) AS len
ORDER BY len DESC
LIMIT 1 UNWIND parts AS part
OPTIONAL MATCH (part)<-[:Has*1..10]-(parent)
RETURN part, LAST(COLLECT(parent))
任何见解都将受到赞赏。
答案 0 :(得分:3)
UNWIND
实际上仍按预期顺序返回行。相反,聚合函数COLLECT()
正在“重新排列”结果行。 neo4j不保证聚合函数的结果行将以任何特定顺序(没有ORDER BY
子句)。
这是一种避免使用聚合的解决方法。它可能适用于您的特定用例,具体取决于您的要求。此查询过滤第二个OPTIONAL MATCH
,以便它包含Has
关系的最长序列(只要最长序列<= 10跳 - 您应根据需要调整此值,或考虑取消最大值)。查询只返回每个结果行中最远的“祖先”,行将保持您期望的顺序。
MATCH (n:Cable { name: 'Cable3' })-[:Connected_to*]-(port:Port)
OPTIONAL MATCH path=(port)-[:Connected_to*]-()
WITH nodes(path) AS parts, length(path) AS len
ORDER BY len DESC
LIMIT 1 UNWIND parts AS part
OPTIONAL MATCH (part)<-[:Has*1..10]-(ancestor)
WHERE NOT (ancestor)<-[:Has]-()
RETURN part, ancestor;