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

时间:2014-09-08 04:26:15

标签: neo4j cypher

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

我的项目有时需要每秒多次写入标有“ChildSession'”的节点,我注意到当我增加'在密码中的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 个答案:

答案 0 :(得分:4)

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

考虑到两件事情,使用COUNT可能不是最快的,如果您要删除ChildSession(也许您不在乎?),则不能保证唯一值。将计数保持为属性可能更快(查询时间)并且产生的开销最小。

我认为实现这一目标的正确方法是在单独的标签上使用MERGE语句,该标签应该通过整个事务锁定Incremental节点(如this Blog Post中所述):

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吗?