将大量节点插入Neo4J

时间:2013-02-20 00:58:33

标签: java neo4j bigdata

我有一个存储在典型MySQL数据库中的表,并且我使用java构建了一个小的解析器工具,以解析并构建一个neo4j数据库。该数据库将具有约4,000万个节点,每个节点具有一个或多个边缘(最多可能有10个边缘)。问题来自我必须创建某些节点的方式。有用户节点,注释节点和主题标签节点。用户节点和主题标签节点必须都是唯一的。我使用以下示例中的代码来确保唯一性:

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 );

}

我考虑过使用批量插入器,但是在执行批量插入时,我还没有找到检查节点是否唯一的方法。所以我的问题是什么是插入所有这些节点的最快方法,同时仍然确保它们保持其唯一性。任何帮助都将一如既往地受到高度赞赏。

3 个答案:

答案 0 :(得分:3)

如果此处有其他人遇到此问题,我想记录自己和同事为了提高速度而能够弄清楚的事情。首先关于数据的一两个说明:

  • 他们占据了大约30%的节点
  • 还有大量的主题标签,因为人们会倾向于散列任何东西
  • 这两项都必须保证唯一

现在,这已经超出了优化的范围。首先,您需要确保每次插入节点时插入循环都完成。我们没有真正的例子可以看到代码看起来像这样(伪代码)

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个节点,而无需使用批量加载器。感谢大家的帮助。

答案 1 :(得分:0)

为什么不在批量插入期间创建本地缓存?您可以使用带有密钥Map和值name的Java NodeId(来自批量插入器)。

答案 2 :(得分:0)

通常只需将它们保存在HashMap中即可。毕竟

之后你将不会拥有那么多的用户和标签

您还可以使用LuceneBatchInserterIndex并使用setCapacity

请参阅:http://docs.neo4j.org/chunked/milestone/batchinsert.html#indexing-batchinsert