在Neo4j中生成友好的id序列

时间:2013-08-22 22:15:38

标签: neo4j cypher

我有一堆关系,我想为子对象创建一个友好的id,以便我可以拥有更友好的URL。

每次我为特定父对象创建子对象时,我都希望自动包含一个按顺序递增的友好ID。因此,第一个孩子将拥有友好ID 1,第二个孩子将拥有友好ID 2,等等。如果孩子被删除,我不想重复使用id。更复杂的是,我想为此做很多这样的关系。

目前我在父节点上缓存一些状态,并在创建子节点时使用它来填充友好ID:

CREATE (o:Foo {name: 'parent', nextChildId: 1})

MATCH (o:Foo)
WHERE o.name = 'parent'
CREATE (o)-[:HAS]->(c:Child {name: 'child1', friendlyId: o.nextChildId})
SET o.nextChildId = o.nextChildId + 1

MATCH (o:Foo)
WHERE o.name = 'parent'
CREATE (o)-[:HAS]->(c:Child {name: 'child2', friendlyId: o.nextChildId})
SET o.nextChildId = o.nextChildId + 1

问题在于,由于两个客户可以尝试同时创建孩子,因此两个孩子有可能最终拥有相同的友好ID。我不知道如何防止这种情况发生。

2 个答案:

答案 0 :(得分:4)

对于其他想要这样做的人,我从Neo4j Google小组获得了解决方法。诀窍是通过删除不存在的属性在节点上创建锁。这序列化了对节点的访问,并防止多个孩子获得相同的ID。

CREATE (o:Foo {name: 'parent', nextChildId: 1})

MATCH (o:Foo)
WHERE o.name = 'parent'
REMOVE o.lock  // non-existent property
CREATE (o)-[:HAS]->(c:Child {name: 'child1', friendlyId: o.nextChildId})
SET o.nextChildId = o.nextChildId + 1

答案 1 :(得分:1)

Neo4j完全ACID compliant。您可以在具有SERIALIZABLE隔离级别的事务中运行此操作,并获取感兴趣节点上的锁定。但请记住,这可能会降低性能。