使用apoc.do.when时RULE planner不支持调用过程的问题
解决RULE planner不支持调用APOC过程的错误
问题回顾
你之前尝试用apoc.do.when处理CSV导入时的节点去重创建问题,结果碰到了这个报错:
Neo.DatabaseError.Statement.ExecutionFailed RULE planner does not support calling procedures
咱们先来拆解下这个问题的根源,再给你可行的解决方案,顺便优化下你的Cypher写法。
错误根源
Neo4j有两个查询规划器:RULE和COST。RULE是比较陈旧的规划器,它压根不支持调用自定义过程(比如APOC库的apoc.do.when)。如果你的Neo4j版本默认用了RULE,或者语句里没指定用COST,就会触发这个错误。
直接解决方案
1. 强制指定COST规划器
在你的Cypher语句最开头加上CYPHER planner=cost,强制让Neo4j用支持过程调用的COST规划器,代码示例:
CYPHER planner=cost LOAD CSV WITH HEADERS FROM "file:///the-file-name.csv" as line FIELDTERMINATOR ',' OPTIONAL MATCH (n:Region) WHERE n.region contains "BLANKEMPTYVIDE" AND n.identifier= line.CODE_TER CALL apoc.do.when( n IS NULL, 'MERGE (r:Region{region: line.TERRITOIRE}) ON CREATE SET r.description=line.TERRITOIRE ON CREATE SET r.identifier=line.CODE_TER ON CREATE SET r.id = toString(id(r)) RETURN r', 'RETURN n AS r', {}) YIELD value WITH value.r AS r,line SET r.identifier=line.CODE_TER SET r.description=line.TERRITOIRE SET r.region=line.TERRITOIRE // 后续代码保持不变...
2. 升级Neo4j版本(推荐)
如果你的Neo4j还是3.x及更早的版本,强烈建议升级到4.x或更高版本。这些新版本默认就用COST规划器,不仅能解决这个问题,还能获得更好的性能、更多的功能,后续踩坑的概率也更低。
额外优化:不用APOC也能实现节点去重
其实你的场景完全可以不用apoc.do.when,用Cypher原生的MERGE和条件判断就能搞定节点去重,代码更简洁还不依赖APOC。比如Region部分可以改成这样:
CYPHER planner=cost LOAD CSV WITH HEADERS FROM "file:///the-file-name.csv" as line FIELDTERMINATOR ',' // 先尝试匹配旧的"BLANKEMPTYVIDE"节点 OPTIONAL MATCH (oldRegion:Region) WHERE oldRegion.region contains "BLANKEMPTYVIDE" AND oldRegion.identifier = line.CODE_TER // 用identifier作为唯一键MERGE新节点,避免重复创建 MERGE (r:Region {identifier: line.CODE_TER}) ON CREATE SET r.region = line.TERRITOIRE, r.description = line.TERRITOIRE, r.id = toString(id(r)) // 不管是新创建还是已存在的节点,都同步最新属性 SET r.region = line.TERRITOIRE, r.description = line.TERRITOIRE // 如果需要清理旧的"BLANKEMPTYVIDE"节点,可以加上这段(按需选择) // WITH r, oldRegion // WHERE oldRegion IS NOT NULL // DETACH DELETE oldRegion // 后续处理City、Sector的逻辑可以照搬这个模式,替换对应的标签和属性就行...
这种写法既实现了你的需求,又更符合Cypher的设计思路,维护起来也更方便。
内容的提问来源于stack exchange,提问作者Schwertfisch
相关产品推荐
相关产品推荐

