Neo4j使用MERGE搭配UNWIND导入字典列表仅生成单节点问题求解
问题原因
你写的MERGE (n:Friend)没有指定匹配属性,逻辑是「匹配任意一个带有Friend标签的节点」,而非「匹配带有对应name属性的Friend节点」。第一次执行时库中没有Friend标签的节点,会创建1个空Friend节点,之后每次UNWIND遍历到新元素时,都会匹配到这个已存在的唯一Friend节点,执行SET n += ind覆盖name属性,最终节点的name就被最后一个元素Teresa覆盖,所以只会生成1个Teresa节点。
修正后的Cypher查询
把MERGE语句加上name属性作为匹配条件即可,不需要提前处理Python端的列表也能实现只生成2个节点的需求:
WITH $batch AS batch UNWIND batch as ind -- 按name属性匹配Friend节点,不存在则创建 MERGE (n:Friend {name: ind.name}) -- 如果字典还有其他属性,可以保留这句做属性更新,只有name的话可以省略 SET n += ind
如果想在Cypher端直接去重减少匹配次数,也可以写成:
WITH $batch AS batch UNWIND batch as ind WITH DISTINCT ind AS unique_ind MERGE (n:Friend {name: unique_ind.name}) SET n += unique_ind
关于是否提前去重后用CREATE替代MERGE的说明
分两种场景判断:
- 如果你可以100%保证两点:① 输入列表已经完全去重,不会有重复的name项;② 目标Neo4j库中不存在任何带有相同name属性的Friend节点,后续也不会有重复导入的需求,那么可以选择先去重后用CREATE,写入性能会比MERGE更高(不需要执行前置匹配查询)。
- 只要不满足上面任意一个条件,更推荐使用MERGE。MERGE会自动做幂等处理,哪怕重复执行查询、或者输入列表有重复项,也不会生成重复的Friend节点,容错性更高。
内容的提问来源于stack exchange,提问作者sprint_6
相关产品推荐
相关产品推荐

