$convert不是万能转换器,必须显式指定input、to及onError/onNull,否则非法值(如"abc"转int)会直接报错中断聚合;它支持"int"、"long"、"double"、"date"等小写类型名,不支持大小写变体或自定义类型。

$convert 不是万能类型转换器,它在聚合管道中能处理类型不一致的字段,但必须显式指定 input、to 和 onError(或 onNull),否则遇到非法值会直接报错中断整个聚合。
为什么 $convert 会突然让聚合失败?
默认情况下,$convert 对无法转换的值(比如把 "abc" 转成 int)抛出异常,而不是返回 null 或跳过。MongoDB 不会静默容错。
- 常见错误现象:
TypeError: can't convert from string to integer(实际错误名更长,但含can't convert关键字) - 典型场景:导入 CSV 后字符串型数字字段(如
"123")、空字符串""、缺失字段null混杂存在 - 必须设置
onError—— 即使只是设为null,也要写出来;不写就崩 - 示例安全写法:
{ $convert: { input: "$age", to: "int", onError: null } }
$convert 的 to 类型有哪些可选值?
不是所有语言类型名都支持。to 只接受 MongoDB 内置的类型标识符,大小写敏感,且部分类型有别名限制。
- 常用合法值:
"int"(32位)、"long"(64位)、"double"、"decimal"、"bool"、"date"、"string"、"objectId" -
"int"不能转超过 2³¹−1 的数,超出会截断或报错(取决于驱动版本),大整数优先用"long" -
"date"要求输入能被解析为 ISO 格式(如"2023-05-01"或"2023-05-01T00:00:00Z"),纯数字时间戳需先用$toDate更稳妥 -
"objectId"仅接受 24 位十六进制字符串,"123"这类会触发onError
和 $toInt / $toDouble 等快捷操作符比有什么区别?
快捷操作符(如 $toInt)本质是 $convert 的封装,但隐式设了 onError: null 和 onNull: null,表面简单,实则掩盖风险。
-
$toInt: "$age"看似简洁,但遇到"12.5"或"12a"直接返回null,你可能误以为原字段就是空 -
$convert强制你直面转换失败的可能性,适合数据清洗阶段做明确兜底逻辑 - 性能差异极小,无需为性能牺牲可控性;真正影响性能的是是否在
$match前做了转换(避免全表扫描) - 若需保留原始错误信息用于日志,只能用
$convert配合onError返回自定义对象,快捷操作符做不到
真正容易被忽略的点是:即使加了 onError,$convert 对 undefined 字段仍按 null 处理——而很多前端传参习惯用 undefined 表示“未填”,后端聚合时它不会触发 onError,但结果也不是你想要的数字。得靠 $ifNull 或前置 $set 统一归零/补缺。

















