MongoDB 8.0起正式弃用$where、$function、$accumulator操作符,其中$where因性能差、无索引支持、高注入风险被优先警告,$function和$accumulator因依赖JS引擎、不支持并行/分片而同步弃用;$expr和原生聚合表达式为推荐替代方案。

MongoDB 4.4 本身仍支持 $where、$function、$accumulator 等操作符,真正开始弃用它们的是从 MongoDB 8.0 起——不是 4.4,也不是 5.0 或 6.0。很多用户误以为“4.4 后就不行了”,其实是把版本号记混了,或者被早期文档的模糊表述误导。
哪些操作符在 MongoDB 8.0+ 被明确标记为弃用
根据官方 2026 年 4 月发布的通告,以下三个操作符在 MongoDB 8.0 开始启用运行时警告,并计划在未来主版本中移除:
-
$where:服务器端 JavaScript 查询谓词,性能差、无法利用索引、易引入注入风险 -
$function:在聚合管道中嵌入 JS 函数,执行开销大,且不支持并行化或分片下推 -
$accumulator:自定义聚合累加器,同样依赖 JS 引擎,与$function共享相同限制
注意:$expr 不在此列,它仍是推荐的替代入口;mapReduce 也同步被弃用,但属于命令级而非操作符。
为什么 $where 优先被劝退,而 $function 还能“苟”到 8.0
$where 在查询层直接执行 JS,每个文档都要调用一次 JS 解释器,连 { $where: "this.x > this.y" } 这种简单表达式都无法走索引,对高并发读场景是硬伤。相比之下,$function 至少限定在聚合阶段,还能配合 $expr 做前置过滤,所以官方给了更长的过渡期。
- 所有含
$where的查询,在 4.4+ 都会触发慢日志告警(但不报错) - 在 8.0+ 中,每次执行
$function会在 mongod 日志里写一条 WARN 级别提示:“$function is deprecated and will be removed in a future release” - 弃用 ≠ 立即失效,但新项目不应再设计依赖它的逻辑
实际迁移时最常卡住的三个替代点
不是所有 JS 逻辑都能用原生聚合操作符 1:1 替换,尤其当涉及字符串正则替换、递归数组遍历、或条件复杂的状态累积时:
- 字符串批量替换(如 URL 域名变更):别再用
$function+String.replace(),改用$replaceAll(5.0+)或嵌套$concat+$substr+$indexOfCP(4.4 兼容) - 动态字段存在性判断:避免
$where: "this.tags && this.tags.length > 0",改用$expr: { $gt: [{ $size: "$tags" }, 0] } - 多条件组合计算(如加权评分):不要写
$function做 if-else 分支,优先拆成$cond+$switch+$add等原生表达式链
如果真绕不开 JS 逻辑(比如需要调用外部 API 或解析非标准时间格式),得接受代价:要么降级到应用层处理,要么用 change stream + worker 模式异步补全,而不是塞进数据库查询里。
检查你代码里是否踩了弃用雷区
搜索项目中所有 MongoDB 查询语句,重点关注以下模式:
- 正则匹配:
/.*$where.*/i、/.*\$function.*/ - 聚合管道中出现
lang: "js"字段 - Shell 或驱动中调用
db.runCommand({ mapReduce: ... })
特别容易被忽略的是:某些 ODM(如 Mongoose)插件或旧版 Admin UI 工具,会在后台自动注入 $where 实现“高级搜索”,这类隐式调用更难定位。建议在测试环境开启 logLevel: 1 并过滤关键词 deprecated,比人工扫代码更快。


















