插入大量的节点到Neo4J
我有一个表存储在一个典型的MySQL数据库,我已经使用java构建了一个小的分析器工具来解析并构建neo4j数据库。该数据库将有约4000万个节点,每个节点具有一个或多个边缘(可能最多有10个边缘)。问题来自我必须创建特定节点的方式。有一个用户节点,评论节点和hashtag节点。用户节点和主题标签节点必须都是唯一的。我使用的代码从下面的例子中,以确保其唯一性:插入大量的节点到Neo4J
public Node getOrCreateUserWithUniqueFactory(String username, GraphDatabaseService graphDb)
{
UniqueFactory<Node> factory = new UniqueFactory.UniqueNodeFactory(graphDb, "users")
{
@Override
protected void initialize(Node created, Map<String, Object> properties)
{
created.setProperty("name", properties.get("name"));
}
};
return factory.getOrCreate("name", username);
}
我曾想过使用批量插入,但在执行我还没有看到一个方法来检查,如果一个节点是独一无二的批量插入。所以我的问题是什么是插入所有这些节点的最快方式,同时仍然确保它们保持唯一性。任何帮助将一如既往地不胜感激。
如果任何人在这里运行到这个问题,我想记录什么我自己和一位同事能够弄清楚为了提高速度。首先一个关于数据或两注:
- 有大量的用户,他们占
- 也有大量的井号标签的节点的大约30%的人会倾向于只哈希不谈
- 这两个必须保证唯一现在
那这就是出路上的优化。首先,formost需要确保插入循环每次插入节点时完成。有这对于我们来看看这样intially代码看起来像这样(伪代码)
Transaction begin
While(record.next()){
parse record
create unique user
create unique hashtag
create comment
insert into graph
}
Transaction success
Transaction finish
虽然这工作确定并完成了相对较快的小型数据集并没有很好地扩展没有实际的例子。因此,我们看一看在每一个功能的目的和重构的代码如下所示:
While(record.next()){
Transaction begin
parse record
create unique user
create unique hashtag
create comment
insert into graph
Transaction success
Transaction finish
}
这大大加快的事情了,但它是不够的,我的同事。所以他发现可以在节点属性上创建Lucene索引,并且我们可以在Unique Node工厂中引用这些索引。这给了我们另一个显着的提速。以至于我们可以在约10秒内插入1,000,000个节点,而无需使用批处理器。感谢大家的帮助。
为什么不在批量插入过程中创建本地缓存?您可以使用java Map
和密钥name
和值NodeId
(来自批量插入器)。
通常情况下,将它们保存在HashMap
中是最简单的。你不会有很多用户和标签的所有
后,您还可以使用LuceneBatchInserterIndex
和使用setCapacity
见:http://docs.neo4j.org/chunked/milestone/batchinsert.html#indexing-batchinsert
“所以他发现Lucene索引可以在节点属性上创建,我们可以在Unique Node工厂中引用这些索引。”你能解释一下吗?我有一个带索引节点属性的索引,例如'名称'并将其用于唯一节点工厂。这是你的意思吗? – joewhite86 2013-07-17 09:49:20
是的,请!我也想知道这个增加neo4j插入速度的神奇咒语是什么! :-) – Stewart 2013-08-21 08:41:08