我有存储在一个典型的MySQL数据库中的表,我已经使用Java,解析,并建立一个数据库的Neo4j内置了一款小分析器工具。 这个数据库将具有〜40万个节点,每个具有一个或多个边缘(具有10层的边缘的可能的最大值)。 这个问题源于我要创建某些节点的方式。 有一个用户节点,注释节点,以及包括hashtag节点。 用户节点和包括hashtag节点必须每个是唯一的。 我使用的代码从下面的例子中,以确保其唯一性:
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索引可以在节点属性创建的,我们可以参考那些在唯一的节点工厂。 这给了我们另一个显著的速度提升。 正因如此,我们就可以插入到10秒百万节点,而不诉诸使用批量加载器。 感谢大家的帮助。
为什么不创建批处理插入过程中的本地缓存? 您可以使用Java Map
与主要name
和值NodeId
(从批量插入)。
通常它是由只是让他们在最简单的HashMap
。 你不会有很多用户和标签毕竟
您也可以使用LuceneBatchInserterIndex
和使用setCapacity
见: http://docs.neo4j.org/chunked/milestone/batchinsert.html#indexing-batchinsert