Neo4j和Cypher - 如何创建/合并链式顺序节点关系(甚至更好的时间序列)?

时间:2016-07-04 06:57:56

标签: neo4j cypher

为了简单起见,作为我的时间序列数据的ETL的一部分,我在每行对应0..370365(370,366个节点,5,555,490个属性 - 不大)中添加了一个序列号属性。后来我添加了第二个属性,并将其命名为“outeseq”(原始)和“ineseq”(第二个),以确定基于关系的完全等价可能会加速一些事情。

我可以让以下两个查询在最多~30k节点(LIMIT 30000)上正常运行,但过去,它只是无休止的等待。我的JVM最大16g(如果它甚至可以在Windows机器上使用它):

MATCH (a:BOOK),(b:BOOK)
WHERE a.outeseq=b.outeseq-1
MERGE (a)-[s:FORWARD_SEQ]->(b)
RETURN s;

MATCH (a:BOOK),(b:BOOK)
WHERE a.outeseq=b.ineseq
MERGE (a)-[s:FORWARD_SEQ]->(b)
RETURN s;

我还添加了这些以期加快速度:

CREATE CONSTRAINT ON (a:BOOK)
ASSERT a.outeseq IS UNIQUE

CREATE CONSTRAINT ON (b:BOOK)
ASSERT b.ineseq IS UNIQUE

我无法获得为整个数据集创建的关系!救命啊!

或者,我也可以获得用参数构建的关系的一些部分,但是还没有弄清楚如何在所有节点到节点的顺序关系中参数化序列,至少在语义上不够通用。这样做。

我描述了查询,但没有看到任何理由让它“爆炸”。

另一个问题:我希望每个关系都有一个属性来表示每个节点或delta-t的时间戳的差异。有没有办法在两个连续节点中取两个值之间的差异,并将它分配给关系?....同时为所有关系?

最后一个问题,如果你有时间 - 我真的很想使用原始数据,只是将定向关系从一个节点的戳连接到具有最小增量的下一个最近的节点,但是没有正确运行在此,因为担心它会导致扫描所有节点以建立每个关系。

在任何人建议我查看KDB或其他数据库的时间序列之前,请允许我说我有一个非常具体的理由想要使用DAG表示。

看起来这应该是这么容易......它可能是,而且我是盲目的。谢谢!

1 个答案:

答案 0 :(得分:0)

创建关系

由于您的查询在30k节点上运行,我建议在所有节点上逐页运行它们。这似乎是可行的,因为outeseqineseq是唯一的和数字的,因此您可以按该属性对节点进行排序,并对一个切片运行查询。

MATCH (a:BOOK),(b:BOOK)
WHERE a.outeseq = b.outeseq-1
WITH a, b ORDER BY a.outeseq SKIP {offset} LIMIT 30000
MERGE (a)-[s:FORWARD_SEQ]->(b)
RETURN s;

运行查询需要大约13次才能更改{offset}以覆盖所有数据。在任何具有neo4j客户端的语言上编写脚本会很好。

更新关系的属性

您可以使用SET之后的MATCH子句为关系指定时间戳增量。假设时间戳是long

MATCH (a:BOOK)-[s:FORWARD_SEQ]->(b:BOOK)
SET s.delta = abs(b.timestamp - a.timestamp);

链接具有最小Delta的节点

当关系内部具有delta属性时,图形将成为加权图形。因此,我们可以应用this approach来计算使用增量的最短路径。然后我们将最短路径的长度(增量的总和)保存到第一个节点和最后一个节点之间的关系中。

MATCH p=(a:BOOK)-[:FORWARD_SEQ*1..]->(b:BOOK)
WITH p AS shortestPath, a, b,
    reduce(weight=0, r in relationships(p) : weight+r.delta) AS totalDelta
    ORDER BY totalDelta ASC
    LIMIT 1
MERGE (a)-[nearest:NEAREST {delta: totalDelta}]->(b)
RETURN nearest;

免责声明:上述查询不应该完全有效,他们只是提示可能解决问题的方法。