我最近开始使用neo4j和图形数据库。 我正在使用这个Api来使我的模型持久化。我已经完成了一切并且工作正常,但我的问题与效率有关。
首先,我将谈论风景。我有几个xml文档转换为一些节点和之间的关系,因为我已经读过这个API仍然不支持批量插入,我一次创建节点和关系。
这是我用于创建节点的代码:
var newEntry = new EntryNode { hash = incremento++.ToString() };
var result = client.Cypher
.Merge("(entry:EntryNode {hash: {_hash} })")
.OnCreate()
.Set("entry = {newEntry}")
.WithParams(new
{
_hash = newEntry.hash,
newEntry
})
.Return(entry => new
{
EntryNode = entry.As<Node<EntryNode>>()
});
因为我需要时间来创建所有节点,我不明白为什么创建一个增量所需的时间如此脂肪。我已经进行了一些测试,并且在创建一个EntryNode的时候停留的时间需要0.2秒才能解决,但是一旦达到500,它就会增加到~2秒。 我还在插入任何数据之前在控制台上手动创建了一个关于EntryNode(哈希)的索引,并使用两个版本进行测试,包括索引和不包含索引。
我做错了吗?这次是正常的吗?
EDITED: @Tatham 谢谢你的回答,真的很有帮助。现在我使用neo4jclient中的foreach语句在2秒内创建1000个节点。
在相关主题上,现在我以这种方式创建节点,我也希望创建关系。这是我现在正在尝试的代码,但是出现了一些错误。
client.Cypher
.Match("(e:EntryNode)")
.Match("(p:EntryPointerNode)")
.ForEach("(n in {set} | " +
"FOREACH (e in (CASE WHEN e.hash = n.EntryHash THEN [e] END) " +
"FOREACH (p in pointers (CASE WHEN p.hash = n.PointerHash THEN [p] END) "+
"MERGE ((p)-[r:PointerToEntry]->(ee)) )))")
.WithParam("set", nodesSet)
.ExecuteWithoutResults();
我想要它做的是,给定一对字符串对,获取节点(它们是唯一的),将字符串值作为属性“hash”并在它们之间创建关系。我尝试了几个变种来做这个查询,但我似乎找不到解决方案。
这可能吗?
答案 0 :(得分:1)
这种方法将非常慢,因为您为要插入的每个节点对Neo4j执行单独的HTTP调用。然后每次通话都是一次交易。最后,您还将节点返回,这可能是一种浪费。
有两种方法可以批量执行此操作。
从https://stackoverflow.com/a/21865110/211747开始,您可以执行以下操作:传递一组对象,然后在Cypher中传递FOREACH
。这意味着对Neo4j进行一次更大的HTTP调用,然后在DB上的单个事务中执行:
FOREACH (n in {set} | MERGE (c:Label {Id : n.Id}) SET c = n)
http://docs.neo4j.org/chunked/stable/query-foreach.html
即将推出的另一个选择是,您可以在Cypher中编写类似的内容:
LOAD CSV WITH HEADERS FROM 'file://c:/temp/input.csv' AS n
MERGE (c:Label { Id : n.Id })
SET c = n