如何在Neo4j中交换两个节点的指定属性及所有关系?
解决Neo4j中两个节点的属性(排除id)与关系交换问题
先修正你原查询的错误
你之前的CREATE (Temp:Student{properties(node1)})写法不符合Cypher语法——Cypher不支持在节点创建的属性字典中直接调用properties()函数。正确的临时节点属性复制方式是先创建空节点,再用SET Temp = node1全量复制属性。
核心需求实现:无需临时节点的方案
1. 属性交换(排除id)
如果节点属性较少,可以直接用WITH子句暂存属性值,避免赋值时互相覆盖:
MATCH (node1 {id: 'id1'}), (node2 {id: 'ID1'}) WITH node1, node2, node1.name AS n1_name, node1.city AS n1_city, node2.name AS n2_name, node2.city AS n2_city SET node1.name = n2_name, node1.city = n2_city, node2.name = n1_name, node2.city = n1_city RETURN node1, node2
如果节点有大量属性,推荐用APOC工具库简化操作(需提前安装APOC),自动排除id属性:
MATCH (node1 {id: 'id1'}), (node2 {id: 'ID1'}) WITH node1, node2, apoc.map.removeKey(properties(node1), 'id') AS props1, apoc.map.removeKey(properties(node2), 'id') AS props2 SET node1 += props2, node2 += props1 RETURN node1, node2
+=运算符会合并属性,仅覆盖除id外的所有字段,保留原节点的id值。
2. 所有关系交换
要把两个节点的全部关系(包括入、出方向)互换,同样用APOC的重构函数批量处理:
MATCH (node1 {id: 'id1'}), (node2 {id: 'ID1'}) // 把node1的出关系转移给node2 OPTIONAL MATCH (node1)-[r1]->(other) CALL apoc.refactor.from(r1, node2) YIELD input // 把node1的入关系转移给node2 OPTIONAL MATCH (other)-[r2]->(node1) CALL apoc.refactor.to(r2, node2) YIELD input // 把node2的出关系转移给node1 OPTIONAL MATCH (node2)-[r3]->(other) CALL apoc.refactor.from(r3, node1) YIELD input // 把node2的入关系转移给node1 OPTIONAL MATCH (other)-[r4]->(node2) CALL apoc.refactor.to(r4, node1) YIELD input RETURN node1, node2
3. 属性+关系交换的完整整合查询
MATCH (node1 {id: 'id1'}), (node2 {id: 'ID1'}) WITH node1, node2, apoc.map.removeKey(properties(node1), 'id') AS props1, apoc.map.removeKey(properties(node2), 'id') AS props2 // 交换属性 SET node1 += props2, node2 += props1 // 交换所有关系 OPTIONAL MATCH (node1)-[r1]->(other) CALL apoc.refactor.from(r1, node2) YIELD input OPTIONAL MATCH (other)-[r2]->(node1) CALL apoc.refactor.to(r2, node2) YIELD input OPTIONAL MATCH (node2)-[r3]->(other) CALL apoc.refactor.from(r3, node1) YIELD input OPTIONAL MATCH (other)-[r4]->(node2) CALL apoc.refactor.to(r4, node1) YIELD input RETURN node1, node2
备选:修正后的临时节点方案
如果仍偏好使用临时节点,正确写法如下:
MATCH (node1 {id: 'id1'}), (node2 {id: 'ID1'}) CREATE (Temp:Student) SET Temp = node1 // 全量复制node1的属性到临时节点 SET node1.name = node2.name, node1.city = node2.city SET node2.name = Temp.name, node2.city = Temp.city DELETE Temp RETURN node1, node2
内容的提问来源于stack exchange,提问作者nik
相关产品推荐
相关产品推荐

