今天遇到一件怪事,每次执行创建语句的时候两个节点之间生成的关系都是双倍的,执行一次生成2条,2次生成4条,4次生成8条,虽然知道是写错了,但没发现具体的漏洞,疑惑了很久。
先说说需求,由于我们的功能涉及到修改某个节点的其他关系,为了实现这个功能,需要先删除掉该节点的所有关系,然后重新加上新的关系,但是担心删除掉关系之后新增关系的时候出现异常,导致关系删除了,但新关系没上,就需要做事务,我在研究了事务相关的文档之后,觉得这玩意有点麻烦,就决定将删除和新增操作放在同一个cypher语句中执行,在此之前做了实验,后半段语句报错的情况下,前半段语句是不会执行成功的,于是就开始了。
最开始我写的cypher语句如下:
MATCH (n)-[r]-() WHERE id(n) = 12230 DELETE r
WITH n
MATCH (n1),(m1),(m2) WHERE id(n1) = 12230 AND id(m1) = 330 and id(m2) = 231
create (n1)-[:ASSS]->(m1), (n1)-[:BSSS]->(m2)
return n1,m1,m2
逻辑很简单,删除掉该节点所有关系,然后找到对应节点,加上新关系。
但是执行的时候遇到了问题
我明明只创建了一条关系,但显示的却有两条,当删除语句和新增语句分开执行时发现生成的关系只有一条,说明我的创建语句是没有问题的,于是我猜想可能和删除时返回值条数有关,在删除时由于有多个n,导致后面的create语句被执行了多次,创建了多条关系。
为了解决这个问题,我用merge替换了create,当创建关系时,先去查询是否存在匹配的关系,如果存在则不创建,修改后的语句如下:
MATCH (n)-[r]-() WHERE id(n) = 12230 DELETE r
WITH n
MATCH (n1),(m1),(m2) WHERE id(n1) = 12230 AND id(m1) = 330 and id(m2) = 231
merge (n1)-[:ASSS]->(m1)
merge (n1)-[:BSSS]->(m2)
return n1,m1,m2
修改后就只创建了一次关系
为了验证我的猜想,我单独执行了删除命令,发现确实只返回了一个节点
但返回了两次