RedisGraph创建单条关系时出现多余重复关系问题
RedisGraph创建关系时生成重复冗余关联的解决方法
问题根因
重复关系来自两个写法问题:
- 匹配阶段写了
MATCH (a:Actor),(m:Movie),没有加任何属性过滤,会对库中所有Actor节点、所有Movie节点做笛卡尔积配对,每一对匹配结果都会触发后续创建逻辑 - 用
CREATE创建关系时不会做存在性校验,只要匹配到节点对就会新建一条关系,哪怕两个节点之间已经存在完全相同的关联,也会重复生成
原问题涉及的执行代码
// 创建《壮志凌云2》电影节点 GRAPH.QUERY movie_graph 'CREATE (m:Movie { title:"Top Gun: Maverick", maincast:"Tom Cruise", realeased:"2022 MAY", Best_Quote:"Its not about the plane,its about the pilot." })' // 创建汤姆克鲁斯演员节点 GRAPH.QUERY movie_graph 'CREATE (a:Actor { name:"Tom Cruise", nationality:"American", Birthdate:"July 3, 1962", Age:"60" })' // 存在问题的建关系语句 GRAPH.QUERY movie_graph "MATCH (a:Actor),(m:Movie) CREATE (a)-[r:ACTED_IN {role:'Maverick'}]->(m) Return m,a "
修复方法
第一步:匹配节点时增加唯一属性过滤,避免全量笛卡尔积
不要无差别匹配所有同标签节点,通过业务上的唯一标识(比如演员姓名、电影标题)精准定位到需要关联的两个节点:
GRAPH.QUERY movie_graph "MATCH (a:Actor {name:'Tom Cruise'}),(m:Movie {title:'Top Gun: Maverick'}) CREATE (a)-[r:ACTED_IN {role:'Maverick'}]->(m) RETURN m,a"
第二步:用MERGE替换CREATE做幂等创建
MERGE会先检查目标路径是否存在,只有不存在时才执行创建,多次执行也不会生成重复数据,适合业务上要求唯一关联的场景:
GRAPH.QUERY movie_graph "MATCH (a:Actor {name:'Tom Cruise'}),(m:Movie {title:'Top Gun: Maverick'}) MERGE (a)-[r:ACTED_IN {role:'Maverick'}]->(m) RETURN m,a"
补充:如果节点本身也存在重复创建的可能,把节点创建部分的
CREATE也替换为MERGE即可,保证同唯一属性的节点仅生成一份。
已生成重复关系的清理语句
如果当前库中已经存在多余的重复关联,执行以下语句可以删除重复项,仅保留一条有效关系:
GRAPH.QUERY movie_graph "MATCH (a:Actor {name:'Tom Cruise'})-[r:ACTED_IN]->(m:Movie {title:'Top Gun: Maverick'}) WITH a,m,collect(r) AS rel_list WHERE size(rel_list) > 1 UNWIND rel_list[1..] AS redundant_rel DELETE redundant_rel"
内容的提问来源于stack exchange,提问作者Karyee Z
相关产品推荐
相关产品推荐

