我有一堆关系,我想为子对象创建一个友好的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。我不知道如何防止这种情况发生。
答案 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
隔离级别的事务中运行此操作,并获取感兴趣节点上的锁定。但请记住,这可能会降低性能。