提问者:小点点

如何在Neo4j中持续增量,Cypher太慢了?


我目前使用Neo4j 2.0和cypher来创建和保存会话。

我的项目有时需要每秒多次写入标记为“ChildSession”的节点,我注意到,当我“增加”cypher中的ChildSession_ID时,我经常ChildSession_ID跳过数字或者是相同的数字。

不确定neo4j/cypher对我的要求是否太慢,但我对此表示怀疑,因为内部Neo4j节点ID通常会增加。

The cypher command i'm using, to increment ChildSession is:

 match (p:ChildSession) with count(p) as Total 
 Create (b:ChildSession{ChildSession_ID:Total + 1 })

人们会期望ChildSession_ID增加,但当我在neo4j浏览器中检查节点时,我得到了以下结果:

match (u:ChildSession) return u,ID(u)

Results:
ChildSession_ID 1
44997
ChildSession_ID 1
44998
ChildSession_ID 1
44999
ChildSession_ID 4
45000
ChildSession_ID 5
45001
ChildSession_ID 6
45002
ChildSession_ID 6
45003
ChildSession_ID 8
45004
ChildSession_ID 8
45005

我无法让neo4j准确地递增。我尝试使用redis和它的hincrby命令递增,然后将这个变量放入我的cypher查询的ChildSession_ID属性中。这种方法有效,但我宁愿用cypher来代替。

可以说只在快速写入时使用redis,但我使用了大量的会话级别,需要neo4j提供的查询功能。

谢谢。


共1个答案

匿名用户

您是否在访问ChildSession标签时添加了任何手动锁定?否则,我希望MATCH语句可以同时发生在多个线程上(没有读锁定)。这样做的结果将是将相同的值传递给您的CREATE语句。

想到两件事情,使用COUNT可能不是最快的,并且如果您要删除ChildSession(也许您不关心?),也不能保证唯一值。将计数维护为属性可能更快(查询时间),并且开销最小。

我认为实现这一点的正确方法是在单独的标签上使用MERGE语句,该标签应该在整个事务中锁定增量节点(如本博客文章所述):

MERGE (nid:Incremental{type:ChildSession})
ON CREATE SET nid.count = 1
ON MATCH SET nid.count = nid.count + 1
RETURN nid.count

警告:虽然我相信这是正确的方法,但如果它在快速异步环境中工作良好,我会被诅咒,这表明锁定的语义学不是我所期望的。

如果你的ChildSession_ID的增量性质不重要,你当然可以产生一个UUID?