Neo4j中call.apoc.do.when引用with传递的rels变量报错怎么办?
解决Neo4j中APOC do.when无法访问外部变量的问题
嘿,这个坑我刚学Neo4j的时候也踩过!问题根本不是REDUCE的锅,而是APOC过程的字符串查询无法直接访问外部作用域的变量——你定义的rels是在CALL apoc.do.when外面的,但那个字符串里的Cypher查询是在独立的执行上下文里运行的,它根本不知道rels是什么变量。
解决方案:显式传递参数给APOC查询
apoc.do.when支持第四个参数,用来传递外部变量作为查询的参数。你只需要做两个小修改:
- 在字符串查询里用
$rels代替直接写rels(参数变量以$开头) - 新增第四个参数,把外部的
rels映射到查询里的$rels参数
修改后的完整查询如下:
MATCH (t1:Title)-[r:TO]->(t2:Title) WHERE t1.tid = '123abc' AND NOT exists((t2)<-[:LIKE|:DISLIKE|:LOVE]-(:User {pid: '456def'})) WITH COLLECT(r) AS rels LIMIT 1 WITH rels CALL apoc.do.when( SIZE(rels) > 0, 'RETURN REDUCE(total = 0, x IN $rels | total + x.weight) AS result', 'RETURN 0 AS result', {rels: rels} // 把外部的rels作为参数传入查询 ) YIELD value RETURN value.result
更简洁的替代方案:不用APOC,直接用CASE表达式
其实你的需求只是根据rels是否为空来返回总和或0,完全可以不用APOC,用Neo4j原生的CASE表达式就能实现,代码更简洁也更直观:
MATCH (t1:Title)-[r:TO]->(t2:Title) WHERE t1.tid = '123abc' AND NOT exists((t2)<-[:LIKE|:DISLIKE|:LOVE]-(:User {pid: '456def'})) WITH COLLECT(r) AS rels LIMIT 1 RETURN CASE WHEN SIZE(rels) > 0 THEN REDUCE(total = 0, x IN rels | total + x.weight) ELSE 0 END AS result
这样就完全避免了APOC变量作用域的问题,对于新手来说也更容易理解和维护。
内容的提问来源于stack exchange,提问作者E. Zeytinci
相关产品推荐
相关产品推荐

