如何使用apoc.periodic.iterate快速动态地将关系三元组的CSV加载到Neo4j中



TL;DR:我如何快速并动态将关系三元组的CSV加载到Neo4j中


编辑:我现在正在运行下面的查询,但速度非常慢;我预计它需要六到七个小时才能完成。如果你知道如何优化这个,请告诉我。

:auto LOAD CSV WITH HEADERS FROM 'file:///etymology.csv.gz' AS row
WITH row WHERE row.related_term_id IS NOT NULL AND row.related_lang IS NOT NULL
CALL {
WITH row
CALL apoc.merge.node([row.lang], {term_id: row.term_id}, {term: row.term, language: row.lang, term_id: row.term_id}) YIELD node AS node_a
CALL apoc.merge.node([row.related_lang], {term_id: row.related_term_id}, {term: row.related_term, language: row.related_lang, term_id: row.related_term_id}) YIELD node AS node_b
CALL apoc.create.relationship(node_a, row.reltype, {reltype: row.reltype}, node_b) YIELD rel RETURN rel
} IN TRANSACTIONS OF 10000 ROWS
RETURN count(*)

数据集

我想快速并动态将数据集加载到Neo4j中。数据集有11列,尽管我只对以下列感兴趣:

term_idlangtermreltyperelated_term_idrelated_langrelated_term

该数据集中有388437行。每一行表示一个关系(reltype(,因此在原始数据集中复制了许多节点(由term_idlangtermrelated-对应物组成(。

架构

这是我设想的Neo4j模式:

节点:

  • 标签:lang
  • 属性:term_idtermlang

关系:

  • 标签:reltype
  • 属性:reltype

[Success]加载节点

我认为先加载节点,然后再加载关系会更容易。为此,我提取了所有唯一的术语(来自term_idlangtermrelated-版本(,并将它们写入一个具有2193634行的CSV中。同样,我创建了3884337个关系三元组(term_idreltyperelated_term_id(的CSV。

由于我想动态分配标签,我认为我需要使用APOC。我成功使用以下方法加载节点:

CALL apoc.periodic.iterate(
"CALL apoc.load.csv('file:///terms.csv') yield map as row return row",
"CALL apoc.create.node(['row.language'], {term_id: row.term_id, term: row.term, language: row.language}) YIELD node RETURN node",
{batchSize:10000, parallel:true}
)

[故障]加载关系

不幸的是,我不知道如何执行类似的查询来加载关系。

我在想一些类似的事情:

:auto USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM 'file:///relationships.csv' AS row
WITH row
MATCH (a {term_id: 'row.term_id'}), (b {term_id: 'row.related_term_id'})
WITH row, a, b
CALL apoc.create.relationship(a, 'row.reltype', {reltype: 'row.reltype'}, b) YIELD rel RETURN rel
CALL apoc.periodic.iterate(
"CALL apoc.load.csv('file:///relationships.csv') yield map as row return row",
"MATCH (a {term_id: row.term_id}), (b {term_id: row.related_term_id}) ",
"CALL apoc.create.relationship(a, row.reltype, {reltype: row.reltype}, b) yield rel return rel",
{batchSize:10000, parallel:true}
)

但是,上述查询的各种排列要么看起来毫无作用,要么抛出错误。

问题/请求

如何快速将这些关系三元组加载到Neo4j中,同时动态分配关系类型/标签?

或者,是否有一个查询可以用于同时(动态(从原始数据集中加载节点和关系?

我相信这个查询相对简单,但作为Neo4j、Cypher和APOC的新手,我无法完全理解。提前感谢!

我认为动态标签的任务是在开始MERGEing之前动态创建CONSTRAINT。因此,您可能需要构建一些允许的脚本/UI

  • 检测CSV的列
  • 选择与ID对应的列
  • 将id和其他列链接到实体
  • 创建CONSTRAINT
  • 创建节点
  • 添加关系

你可能会得到这样的结果:https://youtu.be/Yc0zzDgVFgk(披露:我为Graphileon工作(

最新更新