我是Neo4j的新手,必须有一些我不了解的基础知识。Neo4j,与Cypher命令的批量加载
我在Java中有很多对象,我想用它们来填充Neo4j图形,使用Java驱动程序和Cypher。我的代码是这样的:
// nodes
for (Person person: persons)
session.run (String.format (
"CREATE (:Person { id: '%s', name: \"%s\", surname: \"%s\" })",
person.getId(), person.getName(), person.getSurname()
));
// relations
session.run ("CREATE INDEX ON :Person(id)");
for (Friendship friendship: friendships)
session.run (String.format (
"MATCH (from:Person { id: '%s' }), (to:Person { id: '%s' })\n" +
"CREATE (from)-:KNOWS->(to)\n",
friendship.getFrom().getId(),
friendship.getTo().getId()
));
(事实上,这是稍微复杂一些,因为我有一打节点类型和大约相同数量的关系类型)。
现在,这是非常缓慢的,像加载300k节点和1M关系(在相当快的MacBookPro上,Neo4j占用12/16GB RAM)超过1小时。
我在做错误的方式吗?我应该使用batch inserter吗? (我宁愿能够通过网络访问graphDB)。我会通过将更多插入组合到一个事务中来获得某些东西吗? (从文档中,似乎事务仅用于回滚和隔离需求)。
谢谢,但我认为它不适用于我的情况。 24-15ms没有什么不同,考虑到我的应用程序在3分钟内使用哈希映射填充内部图,而Neo4j需要很长时间才能完成。这是不对的,它应该或多或少地相同。 至于WIND,我认为发送一个列表作为参数最终会变成一个太大的查询,因为我有这么多的节点和边缘。 – zakmck
我的基准可能会关闭,但我强烈建议至少尝试UNWIND。你的有效载荷列表不一定非要全部*你的数据,你可以把它整理出来(就像我在实践中做的那样,而不是上面的例子代码)。如果有效载荷的大小大约为100k,并且可以用N个交易填充边缘,那么相对于N * 100k个别交易将节省大量时间。 – sjc
谢谢@sjc,我看到UNWIND上的观点,我会尝试一下。 – zakmck