Cypher COLLECT 使 UNWIND 以错误的顺序展开

Lun*_*erg 4 collect neo4j longest-path cypher

图要点: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
Run Code Online (Sandbox Code Playgroud)

这个没有 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
Run Code Online (Sandbox Code Playgroud)

此查询未按预期工作,以另一种顺序返回路径中的节点:

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))
Run Code Online (Sandbox Code Playgroud)

任何见解将不胜感激。

cyb*_*sam 5

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;
Run Code Online (Sandbox Code Playgroud)