Neo4j 正在使用同一个密码创建多个节点和关系
Neo4j is creating multiple nodes and relationships with the same cypher
我正在尝试动态生成密码以在 Neo4j (v3.0.4) 上创建节点和关系,但我得到了一些奇怪的结果。
我使用密码查询已经有一段时间了,我在这里看不出我的查询有什么问题
所以我有一个 Neo4j 数据库,它对 :Individuals
的唯一 id
有约束
CREATE CONSTRAINT ON (i:Individual) ASSERT i.id IS UNIQUE
鉴于此,我运行宁以下密码查询:
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
太棒了!预期的结果。
但是如果我 运行 same 再次查询,结果是
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.
并注意第一个节点没有被复制,只有 "child" 个节点及其关系...
我不知道我错过了什么...
谢谢
我认为修复查询的更简单方法是将所有 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)
这样就可以运行多次查询上面的内容,不会再创建节点了。
您只有一个唯一性约束是针对 Individual
个节点的 id
属性。
因为 name
属性 没有唯一性约束,您的 CREATE (c1:Individual {name: "CHILD x"})
子句将始终创建新节点。您需要在创建这些节点时指定 id
属性,以便在您尝试 re-use 现有 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)
如果 child 的节点已经存在(具有相同的 id
),但它没有您要分配给它的名称,上面的查询将名称设置为一个单独的 SET
子句。 (如果您在 MERGE
子句中保留 name
属性,如果具有相同 id
的节点已经存在,但它具有不同的名称,您将得到一个错误。 )
注意:如果 child 已经有 IS_RELATIVE
不再合适的关系,您可能还需要考虑该怎么做。
我正在尝试动态生成密码以在 Neo4j (v3.0.4) 上创建节点和关系,但我得到了一些奇怪的结果。
我使用密码查询已经有一段时间了,我在这里看不出我的查询有什么问题
所以我有一个 Neo4j 数据库,它对 :Individuals
id
有约束
CREATE CONSTRAINT ON (i:Individual) ASSERT i.id IS UNIQUE
鉴于此,我运行宁以下密码查询:
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
太棒了!预期的结果。
但是如果我 运行 same 再次查询,结果是
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.
并注意第一个节点没有被复制,只有 "child" 个节点及其关系...
我不知道我错过了什么...
谢谢
我认为修复查询的更简单方法是将所有 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)
这样就可以运行多次查询上面的内容,不会再创建节点了。
您只有一个唯一性约束是针对 Individual
个节点的 id
属性。
因为 name
属性 没有唯一性约束,您的 CREATE (c1:Individual {name: "CHILD x"})
子句将始终创建新节点。您需要在创建这些节点时指定 id
属性,以便在您尝试 re-use 现有 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)
如果 child 的节点已经存在(具有相同的 id
),但它没有您要分配给它的名称,上面的查询将名称设置为一个单独的 SET
子句。 (如果您在 MERGE
子句中保留 name
属性,如果具有相同 id
的节点已经存在,但它具有不同的名称,您将得到一个错误。 )
注意:如果 child 已经有 IS_RELATIVE
不再合适的关系,您可能还需要考虑该怎么做。