我正在尝试动态生成密码以在Neo4j(v3.0.4)上创建节点和关系,但我得到了一些奇怪的结果。
我一直在使用cypher查询一段时间,我看不出我的查询有什么问题
所以我有一个Neo4j数据库,对id
的唯一:Individuals
有约束
CREATE CONSTRAINT ON (i:Individual) ASSERT i.id IS UNIQUE
鉴于此,我正在运行以下cypher查询:
MERGE (parent:Individual {id:"334717eb182371a126e46d44bde3ef6b"})
SET parent.name = "SOME PARENT NAME"
WITH parent
OPTIONAL MATCH (parent)<-[del:IS_RELATIVE]-(n)
WITH parent, n, del
DELETE del
WITH parent
CREATE (c1:Individual {name:"CHILD 1"})
CREATE (parent)<-[r1:IS_RELATIVE {birth:"2017-02-24"}]-(c1)
CREATE (c2:Individual {name:"CHILD 2"})
CREATE (parent)<-[r2:IS_RELATIVE {birth:"2015-01-23"}]-(c2)
第一次运行它,结果我:
Added 3 labels, created 3 nodes, set 7 properties, created 2 relationships, statement executed in 1201 ms
哪个好极了!预期结果。
但是,如果我再次运行相同的查询,则会产生结果
Added 4 labels, created 4 nodes, set 11 properties, deleted 2 relationships, created 4 relationships, statement executed in 540 ms.
如果我再次运行相同的查询:
Added 8 labels, created 8 nodes, set 21 properties, deleted 4 relationships, created 8 relationships, statement executed in 192 ms.
然后
Added 16 labels, created 16 nodes, set 41 properties, deleted 8 relationships, created 16 relationships, statement executed in 583 ms.
请注意,第一个节点没有重复,只有“孩子”节点与他们的关系......
我不知道我错过了什么...... 感谢
答案 0 :(得分:1)
我认为修复查询的更简单方法是按CREATE
更改所有MERGE
语句,如下所示:
MERGE (parent:Individual {id:"334717eb182371a126e46d44bde3ef6b"})
SET parent.name = "SOME PARENT NAME"
WITH parent
OPTIONAL MATCH (parent)<-[del:HAS_CHILDREN]-(n)
WITH parent, n, del
DELETE del
WITH parent
MERGE (c1:Individual {name:"CHILD 1"})
MERGE (parent)<-[r1:HAS_CHILDREN {birth:"2017-02-24"}]-(c1)
MERGE (c2:Individual {name:"CHILD 2"})
MERGE (parent)<-[r2:HAS_CHILDREN {birth:"2015-01-23"}]-(c2)
这样,您可以多次运行上述查询,并且不会再次创建节点。
答案 1 :(得分:0)
您对id
个节点的Individual
属性只有唯一性约束。
由于name
属性没有唯一性约束,因此CREATE (c1:Individual {name: "CHILD x"})
子句将始终创建新节点。在创建这些节点时,您需要指定id
属性,以便在尝试重新使用现有id
时查看约束错误。
此外,您应该使用MERGE
而不是CREATE
,以便在违反约束时不必处理错误,从而不会中止查询。
例如:
MERGE (parent:Individual {id:"334717eb182371a126e46d44bde3ef6b"})
SET parent.name = "SOME PARENT NAME"
WITH parent
OPTIONAL MATCH (parent)<-[del:IS_RELATIVE]-()
DELETE del
WITH parent
MERGE (c1:Individual {id: "1234567890"})
SET c1.name = "CHILD 1"
CREATE (parent)<-[r1:IS_RELATIVE {birth:"2017-02-24"}]-(c1)
MERGE (c2:Individual {id: "2345678901"})
SET c2.name = "CHILD 2"
CREATE (parent)<-[r2:IS_RELATIVE {birth:"2015-01-23"}]-(c2)
如果已存在子节点(具有相同的id
),但它没有您要分配给它的名称,则上述查询会在单独的SET
子句中设置名称。 (如果将name
属性保留在MERGE
子句中,如果已存在具有相同id
的节点,但它具有不同的名称,则会出现错误。)
注意:如果孩子已经拥有不再合适的IS_RELATIVE
关系,您可能还需要考虑该怎么做。