Neo4j Cypher:除了常规排序之外的拓扑排序?

Ase*_*ore 5 graph neo4j cypher

假设我有一个如下所示的节点树:

\n\n

在此输入图像描述

\n\n

数字对应于我通常想要排序的某个值。(可能是时间,也可能是某种分数,等等。)

\n\n

如果我返回按该数字排序的它们,我当然会得到这样的排序:

\n\n
1, 2, 3, 4, 5, 6, 7, 8, 9\n
Run Code Online (Sandbox Code Playgroud)\n\n

这通常很好,但除了这种排序之外,我想应用父母总是在孩子之前排序的约束。所以我真正想要的是这样的:

\n\n
3, 2, 1, 4, 5, 6, 7, 8, 9\n
Run Code Online (Sandbox Code Playgroud)\n\n

你可以看到这看起来几乎是一样的;我们刚刚颠倒了1, 2, 3顺序3, 2, 1的顺序。

\n\n

有没有办法通过 Neo4j Cypher 查询实现这种排序?

\n\n

\xe2\x80\x94

\n\n

这是一个可以使用这棵树的实时控制台示例:

\n\n

http://console.neo4j.org/r/l9mav2

\n\n

这是我到目前为止的查询:

\n\n
MATCH path=( ({i: 3}) <-[:parent*0..]- (node) )\nRETURN node, node.i, LENGTH(path)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我只是不确定如何使用此信息:

\n\n
    \n
  • 如果我ORDER BY node.i,我会得到第一种。

  • \n
  • 如果是我ORDER BY LENGTH(path),那就太激进了。例如9之前5, 6, 7, 8

  • \n
  • 以任何顺序将两者结合起来也不起作用。

  • \n
\n\n

这可能吗?谢谢!

\n

Eve*_*man 2

这感觉有点老套,但也许它会起作用,具体取决于树的大小的可预测程度:

MATCH path=(root:Node { i: 3 })<-[:parent*0..]-(node:Node)
WITH nodes(path)[-1] as n,[x IN nodes(path)| x.i] AS o
ORDER BY o[0], coalesce(o[1], -1), coalesce(o[2], -1), coalesce(o[3], -1) // and so forth
RETURN n
Run Code Online (Sandbox Code Playgroud)

其中合并中的 -1 肯定低于属性中任何可能的值.i

这是利用字符串比较的属性来发挥我们的优势的另一个想法:

MATCH path=(root:Node { i: 3 })<-[:parent*0..]-(node:Node)
WITH nodes(path)[-1] AS n,[x IN nodes(path)| x.i] AS o, 
     reduce(maxLen=0, p IN root<-[:parent*]-()|CASE WHEN maxLen < length(p)
                                                   THEN length(p)
                                                   ELSE maxLen END ) AS maxLen
ORDER BY reduce(acc='', x IN range(0,maxLen)|acc+coalesce(str(o[x]), ''))
RETURN n,reduce(acc='', x IN range(0,maxLen)|acc+coalesce(str(o[x]), ''))
Run Code Online (Sandbox Code Playgroud)

您可以获取如图所示的最大路径长度,也可以将 maxLen 设置为非常高的数字。