Neo4j含新关系类型的Upsert实现问题求助
解决Neo4j中跨关系类型的Upsert(覆盖关系类型与属性)问题
你的核心问题在于:Neo4j的MERGE操作关系时必须明确指定关系类型,无法仅通过属性集合来匹配任意类型的关系。而你的需求是匹配两个节点间所有包含e1_id、e2_id、model指定值的关系(不管原类型),并完全替换为新的关系类型和属性——由于Neo4j的关系类型不可修改,这种场景下必须删除旧关系后重建新关系,具体实现如下:
正确的Cypher查询
方式一:处理存在旧关系的场景(无旧关系则跳过删除直接创建)
MERGE (snapchat:ORG{name:'ORG_snapchat'}) MERGE (xbox:ORG{name:'ORG_xbox'}) // 匹配所有符合属性条件的旧关系并删除 MATCH (xbox)-[old_edge]->(snapchat) WHERE old_edge.e1_id = '111' AND old_edge.e2_id = '222' AND old_edge.model = 'TEST' DELETE old_edge // 创建新的目标关系并设置属性 CREATE (xbox)-[new_edge:OPPO]->(snapchat) SET new_edge = { e1_id:'111', e2_id:'222', url:'test.com', date:'2022-09-09', model:'TEST', context:'THIS IS A TEST' }
方式二:兼容有无旧关系的通用场景
如果不确定是否存在旧关系,用OPTIONAL MATCH替代MATCH,避免无旧关系时报错:
MERGE (snapchat:ORG{name:'ORG_snapchat'}) MERGE (xbox:ORG{name:'ORG_xbox'}) // 可选匹配旧关系,不存在则跳过删除步骤 OPTIONAL MATCH (xbox)-[old_edge]->(snapchat) WHERE old_edge.e1_id = '111' AND old_edge.e2_id = '222' AND old_edge.model = 'TEST' DELETE old_edge // 创建新关系并赋值 CREATE (xbox)-[new_edge:OPPO]->(snapchat) SET new_edge = { e1_id:'111', e2_id:'222', url:'test.com', date:'2022-09-09', model:'TEST', context:'THIS IS A TEST' }
关键说明
为什么不能用
MERGE?MERGE关系要求必须指定关系类型,只能匹配「特定类型+属性」的关系,无法跨类型匹配仅符合属性条件的关系,这不符合你需要覆盖任意类型旧关系的需求。为什么必须删除重建?
Neo4j的关系类型是不可变属性,一旦创建无法修改。如果你的需求只是更新关系属性而不改变类型,可以用MERGE指定类型后通过ON MATCH SET更新,但如果需要更换关系类型,只能删除旧关系再创建新的。
内容的提问来源于stack exchange,提问作者Falcondance
相关产品推荐
相关产品推荐

