我是Neo4j的新手,我想为一组匹配的节点创建一个运行总计。这就是我所拥有的
MATCH n RETURN REDUCE(shares = 1000, p IN COLLECT(n) | shares - p.shares)
这只是从股票中减少并显示单个结果,但我期待的是:
shares total
100 100
100 200
100 300
答案 0 :(得分:3)
是的,您可以这样做,但您的节点上需要itemID
或类似的,以便为它们提供订购,否则您无法执行运行总计。以下是它的工作原理:
MATCH (f:F)
WITH f
OPTIONAL MATCH (g:F)
WHERE g.itemID<f.itemID
RETURN f.itemID, f.shares, sum(g.shares) + f.shares
ORDER BY f.itemID ASC;
在这里,我假设您在每个节点上都有itemID
。这是必要的,因为如果您不知道哪些节点之前或哪些节点小于其他节点,则无法计算运行总计。但是如果你确实有像itemID这样的字段,那么你对itemID小于你正在查看的那些项目进行额外的可选匹配,然后你总结这些共享。这提供了准确的运行总量。
这不是一个非常有效的查询,因为你会总结并不断重新求和。假设你有4个节点;第一个总和没什么。第二个是一个。第三个总和为2(第二次为一个)。第四个总和三(一个是第三次,一个是第二次)。所以这需要做很多额外的工作。
我们在这里做的是一个没有可变变量值的黑客攻击。如果我需要执行此查询,我通常会从java / javascript / python /中执行此操作。我可能只是得到shares
值并在cypher之外计算自己的运行总数。
答案 1 :(得分:0)
试试这个:
MATCH (n:Item)
RETURN sum(n.shares) as sum, collect(n.shares) as shares
答案 2 :(得分:0)
here使用不同的方法回答了Mark Needham这个问题:
WITH [100, 100, 100, 200, 300, 500] AS allShares
UNWIND RANGE(0, LENGTH(allShares)-1) AS idx
RETURN allShares[idx],
REDUCE(acc = 0,
value in (allShares[idx] + allShares[..idx]) |
acc + value) AS cumulative
- ==> +-----------------------------+
- ==> | allShares[idx] | cumulative |
- ==> +-----------------------------+
- ==> | 100 | 100 |
- ==> | 100 | 200 |
- ==> | 100 | 300 |
- ==> | 200 | 500 |
- ==> | 300 | 800 |
- ==> | 500 | 1300 |
- ==> +-----------------------------+
- ==> 6 rows
我还没有在大型数据集上测试过它的性能,但乍一看它看起来会比接受的答案快得多。