【问题标题】:Why Neo4j CSV loader doesn't increment the load with large number of records为什么 Neo4j CSV 加载器不会增加大量记录的负载
【发布时间】:2017-11-29 15:15:37
【问题描述】:

我有一个包含以下列的 csv 文件-

Child_Object_ID;
Child_Object_Name;
Child_Object_Type;
Parent_Object_ID;
Parent_Object_Name;
Parent_Object_Type

顾名思义,包含 (Child_Object_ID Child_Object_Name and Child_Object_Type) 的节点是 (Parent_Object_ID Parent_Object_Name and Parent_Object_Type) 的子节点。这些父节点可能是其他父节点的子节点。

此 CSV 文件包含 110 万条记录。我面临的问题是,在加载 100K 记录之后,我在加载过程中看不到任何增量。但是加载过程一直在运行,但我没有看到正在构建任何其他节点或关系。

我正在使用以下 Cypher 查询将数据加载到 Neo4j Windows 版本中-

CREATE INDEX ON :Object(Object_ID)
CREATE INDEX ON :Object(Object_ID, Object_Name, Object_Type)
CREATE INDEX ON :Object(Object_Type)

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///file1.csv" AS csvLine
MERGE  (object1:Object {Object_ID:csvLine.CHILD_OBJECT_ID, Object_Name:csvLine.CHILD_OBJECT_NAME, Object_Type:csvLine.CHILD_OBJECT_TYPE})
MERGE  (object2:Object {Object_ID:csvLine.PARENT_OBJECT_ID, Object_Name:csvLine.PARENT_OBJECT_NAME, Object_Type:csvLine.PARENT_OBJECT_TYPE})
MERGE (object1)-[:Child_Of]->(object2)

【问题讨论】:

  • 是否可以选择使用命令行 CSV 导入工具?如果你可以从一个空数据库开始,命令行工具会快很多,并且应该在一分钟内加载 110 万条记录。
  • 嗨 Gabor Szarnyas,是的,我正在将它加载到一个空数据库中。我下载了 Windows 版本的 Neo4j。那么windows版本也有命令行工具?
  • 是的,它在 Windows 版本中可用,在 bin 目录中。
  • 要使用导入工具,您需要至少有两个 CSV:一个用于节点,另一个用于关系,都遵循特定的 header format。正如我在第一条评论中所说,这个加载器比LOAD CSV 快很多,但是,它需要一些修补。因此,只有在加载时间确实是一个问题时才值得这样做(即,对于您的用例来说,大约 1 小时的加载时间是不可接受的)。

标签: neo4j


【解决方案1】:

您的负载查询的一个问题是计划中有Eager 操作,这将阻止PERIODIC COMMIT 批处理(您应该在此查询的查询输入框中看到警告,查看警告消息) .

如果没有批处理,您的导入可能会遇到内存问题。

为避免急切操作,请尝试仅使用单个变量合并所有节点的导入查询。完成后,对子节点和父节点运行一个使用 MATCH 的加载(它将与现有节点匹配),然后 MERGE 关系。

这是关于避免急切操作的article(较旧,但仍然适用)。

【讨论】:

  • 嗨 InverseFalcon,我试过你的建议,效果很好。总共只需 7 分钟即可加载所有数据。
【解决方案2】:

以下是更新后的 Cypher 查询(根据 InverseFalcon 建议重写):

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///file1.csv" AS csvLine
MERGE  (object1:Object {Object_ID:csvLine.CHILD_OBJECT_ID, Object_Name:COALESCE(csvLine.CHILD_OBJECT_NAME, 'NA'), Object_Type:csvLine.CHILD_OBJECT_TYPE, Folder:COALESCE(csvLine.CHILD_FOLDER, 'NA')})


USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///file1.csv" AS csvLine
MERGE  (object2:Object {Object_ID:csvLine.PARENT_OBJECT_ID, Object_Name:COALESCE(csvLine.PARENT_OBJECT_NAME, 'NA'), Object_Type:csvLine.PARENT_OBJECT_TYPE, Folder:COALESCE(csvLine.PARENT_FOLDER, 'NA')})


USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///file1.csv" AS csvLine
MATCH (a:Object {Object_ID:csvLine.CHILD_OBJECT_ID})
MATCH (b:Object {Object_ID:csvLine.PARENT_OBJECT_ID})
MERGE (a)-[:CHILD_OF]->(b)

【讨论】:

  • 您需要进行其他更改才能获得良好的性能。对于加载 :Object 节点的第 1 部分和第 2 部分查询,您希望仅对唯一值(例如 Object_ID)进行 MERGE,并使用 ON CREATE SET 设置剩余的非唯一值。
  • 哦,明白了。再次感谢 InverseFalcon!
猜你喜欢
  • 2019-07-16
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多