【问题标题】:Neo4j and Cypher - How can I create/merge chained sequential node relationships (and even better time-series)?Neo4j 和 Cypher - 如何创建/合并链式顺序节点关系(甚至更好的时间序列)?
【发布时间】:2016-07-04 06:57:56
【问题描述】:

为了简单起见,作为时间序列数据的 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 的时间戳差异。有没有办法获取两个顺序节点中两个值之间的差异,并将其分配给关系?....同时为所有关系?

最后一个 Q,如果你有时间的话——我真的很想使用原始数据,并将直接关系从一个节点的戳记链接到具有最小增量的下一个最近节点,但运行不正确这是因为担心它会导致扫描所有节点以建立每个关系。

在有人建议我使用 KDB 或其他数据库来获取时间序列之前,让我说我有一个非常具体的理由想要使用 DAG 表示。

看起来这应该很容易......它可能是而且我是盲人。谢谢!

【问题讨论】:

  • 另外一点 - 我尝试使用“LOAD CSV”从代理邻接列表中创建关系,但无法使其正常工作。我修改了我可以在网上找到的 4 或 5 个示例,但无法使这种方法发挥作用。如果有人有一个更接近我所追求的代码 sn-p,那可能就是票。 CSV 有 ineseq: toInt(line.ineseq), outeseq: toInt(line.outeseq), timestamp: toFloat(line.timestamp) 可用。

标签: neo4j cypher


【解决方案1】:

建立关系

由于您的查询在 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;

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

更新关系的属性

您可以使用MATCH 后面的SET 子句将时间戳增量分配给关系。假设时间戳是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;

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

【讨论】:

  • 奥列格 - 我要去这个旋转。实际上,在让它运行大约 12 小时后,我开始查询以建立所有关系,但我即将处理更大的数据集,并且我正在祈祷你的分页方案是否可以工作。如果没有,我将不得不尝试不同的图形数据库。感谢您的“具有最小 Delta 的链接节点”
  • 我很欣赏您的“以最小增量链接节点”方法,但我希望找到一种方法来从一开始就在没有关系的情况下创建/合并顺序时间戳节点上的关系(例如,不依赖于任何先前存在的加权关系)。无论哪种方式,我都会在运行后发布一条关于应用您的分页方案的说明。
  • 非常感谢您的回复!
  • 我担心neo4j 是关于关系的,它会以另一种方式运行缓慢。当没有关系时,MATCH (a), (b) 子句将从n 节点中生成n!/(2! *(n-2)!)“行”。这就像对关系数据库中的所有表进行交叉连接。拥有辅助关系会大大加快处理速度,之后可以删除它们。
  • 谢谢奥列格!我怀疑发生了类似的事情,我什至尝试使用索引来生成关系。您的辅助关系想法是我一直在尝试通过添加序列来实现的,但您的建议让我认为一组具有不同标签的重复节点可能有助于避免搜索全部延迟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
相关资源
最近更新 更多