Neo4j加载CSV导入失速

时间:2015-06-28 13:18:03

标签: neo4j cypher

在玩玩具数据集之后,这是我第一次尝试使用与工作项目相关的数据。简而言之,在跛行将我的几乎所有数据都收集到Neo4j后,我的上一个查询只是停滞不前。查看截图。

enter image description here

注意:我通过将查询粘贴到浏览器工具中来对我的查询进行原型设计,但我的长期计划是将所有命令保存在.cql文件中,我可以在工作站上编写脚本以便每晚执行分析

要为我的问题添加上下文,我正在我的macbook上进行原型设计。

  • 8gb ram
  • 2.2 ghz intel core i7
  • osx 10.9.5
  • 2.2.0社区

我正在处理的文件(行/列)。我没有导入每一列,只是更容易控制当前的数据集。

  • Ability.csv = 3/1
  • brm.csv = 276992/34
  • cont.sv = 80093/17
  • email chain.csv = 199143/34(这是我唯一无法进入的数据)
  • 首先发送电子邮件last.csv = 77849/20
  • recs.csv = 77962/20
  • templates_topics.csv = 29/3
  • templates.csv = 49/4
  • topics.csv = 13/1
  • vendors = 5/1

我为neo4j手动设置的唯一配置选项位于neo4j-wrapper.conf,我将wrapper.java.initmemorywrapper.java.maxmemory设置为4096。我在寻找类似的问题之后做了这个。

我在门外进行了这些更改,因为在浏览器中,我收到了在处理查询时数据库已断开连接的错误消息。

最后,因为我的数据与工作有关,所以我无法提供测试数据。但是,我可以链接到我的密码查询。

Constraint and LOAD CSV .cql file

非常感谢任何帮助和建议。我非常有信心这是我的用户错误,但我肯定会在接下来的步骤方面走上正轨。

2 个答案:

答案 0 :(得分:2)

避免在LOAD CSV中急切加载。它不尊重PERIODIC COMMIT。请参阅Mark Needham的article作为详细解释。

答案 1 :(得分:2)

我会把这个分开,一次创建节点并创建第二个关系:

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:///Users/btibert/Dropbox/Projects/bentley-search-neo4j/data/templates.csv" AS row
WITH row
MATCH (r:Vendor {name:row.vendor})
WITH row, r
MERGE (p:Template {name:row.template_clean})
MERGE (v:Version {version:row.template_ver})
MERGE (p)-[:FROM_VERSION]->(v)
MERGE (p)-[:CREATED_BY]->(r);

您可以在计划中清楚地看到 Eager 操作。

我的意思是,如果你只有几千行并不重要。但如果它走向数十万或数百万,则拉入所有数据会占用更多内存。

+----------------+------------------------------------+------------------------------------------------------------------------------------------------+
|       Operator |                        Identifiers |                                                                                          Other |
+----------------+------------------------------------+------------------------------------------------------------------------------------------------+
|    EmptyResult |                                    |                                                                                                |
| UpdateGraph(0) | anon[270], anon[301], p, r, row, v |                                                                                   MergePattern |
| UpdateGraph(1) |            anon[270], p, r, row, v |                                                                                   MergePattern |
| UpdateGraph(2) |                       p, r, row, v | MergeNode; row.template_clean; :Template(name); MergeNode; row.template_ver; :Version(version) |
|          Eager |                             r, row |                                                                                                |
|    SchemaIndex |                             r, row |                                                                      row.vendor; :Vendor(name) |
|        LoadCSV |                                row |                                                                                                |
+----------------+------------------------------------+------------------------------------------------------------------------------------------------+

我可能会将此更改为非关键属性的ON CREATE SET变体: 此外,如果每个学生有多行,则可以使用WITH DISTINCT toInt(row.pidm) as pidm, ....来减少必须运行的合并次数。

LOAD CSV WITH HEADERS FROM "recs.csv" AS row
WITH row
MERGE (s:Student {pidm:toInt(row.pidm)})
ON CREATE SET s.hash_pidm=toInt(row.hash_pidm), ....;

这个我分为两个陈述,每个关系一个,否则你可能得到太多的匹配: (而且你不需要WITH s)

LOAD CSV WITH HEADERS FROM "...recs.csv" AS row
WITH row
MATCH (s:Student {pidm: toInt(row.pidm)} )
MATCH (v:Vendor {name: row.vendor} )
MATCH (a:Ability {name: row.ability} )
WITH row, s, v, a
MERGE (s)-[:PURCHASED_FROM]->(v)
MERGE (s)-[:HAS_ABILITY]->(a);

会变成:

LOAD CSV WITH HEADERS FROM "...recs.csv" AS row
MATCH (s:Student {pidm: toInt(row.pidm)} )
MATCH (v:Vendor {name: row.vendor} )
MERGE (s)-[:PURCHASED_FROM]->(v);


LOAD CSV WITH HEADERS FROM "...recs.csv" AS row
MATCH (s:Student {pidm: toInt(row.pidm)} )
MATCH (a:Ability {name: row.ability} )
MERGE (s)-[:HAS_ABILITY]->(a);

在这里,我还会自己创建联系人。 (再次使用ON CREATE SET) 并在单独的声明中做学生关系:

LOAD CSV WITH HEADERS FROM "....cont.csv" AS row
MERGE (c:Contact {cid:row.cid}) ON CREATE SET ....;

LOAD CSV WITH HEADERS FROM "...cont.csv" AS row
MATCH (s:Student {pidm:toInt(row.pidm)} )
MATCH (c:Contact {cid:row.cid})
MERGE (s)-[:HAS_CONTACT]->(c);

我也会把这个分成两个陈述:

LOAD CSV WITH HEADERS FROM "...cont.csv" AS row
WITH row WHERE toInt(row.seqnum) = 1
MATCH (s:Student {pidm:toInt(row.pidm)}) 
MATCH (f:Contact {cid:row.first_cont})
MERGE (s)-[:FIRST]->(f);

LOAD CSV WITH HEADERS FROM "...cont.csv" AS row
WITH row WHERE toInt(row.seqnum) = 1
MATCH (s:Student {pidm:toInt(row.pidm)}) 
MATCH (l:Contact {cid:row.last_cont})
MERGE (s)-[:LAST]->(l);

将这一部分拆分为电子邮件创建,然后通过msg-id将其连接到学生:

LOAD CSV WITH HEADERS FROM "...brm.csv" AS row
MERGE (e:Email {msgid:row.msgid}) ON CREATE SET ... ;

LOAD CSV WITH HEADERS FROM "file:///Users/btibert/Dropbox/Projects/bentley-search-neo4j/data/brm.csv" AS row
MATCH (s:Student {pidm:toInt(row.pidm)}) 
MATCH (e:Email {msgid:row.msgid})
MERGE (s)-[:WAS_SENT]->(e);

HTH Michael