1

我有一堆关系,我想为子对象创建一个友好的 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,因为两个客户端可以同时尝试创建孩子。我不确定如何防止这种情况发生。

4

2 回答 2

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
于 2013-08-26T19:53:11.707 回答
1

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

于 2013-08-23T01:26:20.257 回答