我目前正在使用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提供。
感谢。
答案 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吗?