Java 将大量节点插入Neo4J
我在一个典型的MySQL数据库中存储了一个表,并使用java构建了一个小型解析器工具,用于解析并构建一个neo4j数据库。该数据库将有约4000万个节点,每个节点有一条或多条边(最多可能有10条边)。问题来自于我必须创建某些节点的方式。有一个用户节点、注释节点和hashtag节点。用户节点和hashtag节点必须是唯一的。我使用以下示例中的代码来确保唯一性:Java 将大量节点插入Neo4J,java,neo4j,bigdata,Java,Neo4j,Bigdata,我在一个典型的MySQL数据库中存储了一个表,并使用java构建了一个小型解析器工具,用于解析并构建一个neo4j数据库。该数据库将有约4000万个节点,每个节点有一条或多条边(最多可能有10条边)。问题来自于我必须创建某些节点的方式。有一个用户节点、注释节点和hashtag节点。用户节点和hashtag节点必须是唯一的。我使用以下示例中的代码来确保唯一性: public Node getOrCreateUserWithUniqueFactory( String username, GraphD
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 );
公共节点getOrCreateUserWithUniqueFactory(字符串用户名,GraphDatabaseService graphDb)
{
UniqueFactory工厂=新的UniqueFactory.UniqueNodeFactory(图形“用户”)
{
@凌驾
受保护的void初始化(创建节点,映射属性)
{
created.setProperty(“name”,properties.get(“name”);
}
};
返回factory.getOrCreate(“名称”,用户名);
}
我曾考虑过使用批插入器,但在执行批插入时,我没有看到检查节点是否唯一的方法。因此,我的问题是,在确保节点保持唯一性的同时,插入所有这些节点的最快方法是什么。非常感谢您的帮助。为什么不在批插入过程中创建本地缓存?您可以使用带有键
名称和值节点ID
(来自批插入器)的java映射
。通常最简单的方法是将它们保存在哈希映射
中。毕竟你不会有那么多的用户和标签
您还可以使用LuceneBatchInserterIndex
和setCapacity
请参阅:如果这里的其他人遇到这个问题,我想记录下我和一位同事为了提高速度所能想出的办法。首先,对数据做一两个注释:
- 用户数量庞大,约占节点的30%
- 还有大量的hashtag,因为人们倾向于散列任何东西
- 必须保证这两个都是独一无二的
现在,这已经不是优化的方式了。首先,您需要确保每次插入节点时插入循环都已完成。对于我们来说,没有真正的例子可以看到这样的代码(伪代码)
虽然这在小数据集上运行正常,并且完成得相对较快,但扩展性不好。因此,我们查看了每个函数的用途,并将代码重构为如下所示:
While(record.next()){
Transaction begin
parse record
create unique user
create unique hashtag
create comment
insert into graph
Transaction success
Transaction finish
}
这大大加快了速度,但对我的同事来说还不够。因此,他发现可以在节点属性上创建Lucene索引,我们可以引用唯一节点工厂中的索引。这给了我们另一个显著的速度提升。如此之多以至于我们可以在10秒内插入1000000个节点,而无需使用批处理加载程序。感谢大家的帮助。“因此他发现可以在节点属性上创建Lucene索引,我们可以引用唯一节点工厂中的索引。”请您进一步解释一下?我有一个带有索引节点属性的索引,例如“name”,并将其用于唯一节点工厂。这就是你的意思吗?是的,求你了!我还想知道提高neo4j插入速度的魔法咒语是什么!:-)
While(record.next()){
Transaction begin
parse record
create unique user
create unique hashtag
create comment
insert into graph
Transaction success
Transaction finish
}