$convert是处理混合类型字段的唯一可靠手段,必须显式指定input(如"$timestamp")和to(小写准确类型名),缺一不可,否则聚合失败;建议配置onerror/onnull防中断。

直接用 $convert,别绕路。它不是“可选项”,而是处理混合类型字段的唯一可靠手段——尤其当同一字段存了 string、number、date 甚至 null 时。
为什么 $convert 必须显式写 input 和 to
这两个字段缺一不可,否则聚合直接失败,报错类似 Missing expected argument to $convert: input。常见错误是把 input 写成字面量(比如 "timestamp")或表达式嵌套(比如 "$timestamp.toString()"),正确写法只能是带 $ 前缀的字段引用:"$timestamp"。
-
to的值必须小写且拼写准确:"string"、"int"、"date"、"double"—— 写成"String"或"DATE"会静默失败或报Invalid type specification - 不设
onError或onNull时,遇到非法输入(如"Sunday"转date)整个 pipeline 就中断;建议统一设为null或默认值,比如onError: null, onNull: null - 示例:把可能混杂的时间字段转成标准日期:
{$project: {cleaned_at: {$convert: {input: "$timestamp", to: "date", onError: null, onNull: null}}}}
$toLong 看似简洁,但限制极多
它只是 $convert 的语法糖,等价于 {$convert: {input: ..., to: "long"}},但只在 MongoDB 3.6+ 可用。如果你用的是 3.4.x(比如 3.4.23),$toLong 会直接报错 unknown operator: $toLong。
- 只接受能无损转为 64 位有符号整数的输入:支持
int、long、double(小数部分截断)、纯数字字符串(如"12345") - 拒绝
bool(true/false报错),而$convert默认转成1/0 - 字符串含非数字字符(如
"12abc"或"12.34")也会失败,不像$convert可靠兜底 - 示例(仅限 3.6+):
{$project: {user_id_long: {$toLong: "$user_id_str"}}}
只转字符串?优先用 $toString
当源字段已知是 number、bool、date 或 null,目标只是字符串时,$toString 更轻量、更安全:它不依赖 onError 配置,也不会因非法输入中断 pipeline。
- 对
null返回空字符串"",对缺失字段也返回"";而$convert默认返回null,需靠onNull显式控制 - 不支持直接转
array或object,会报Cannot convert ARRAY to string;此时必须先用$map或$reduce处理子项 - 如果源字段本身就是
string,$toString直接透传,零开销;$convert则多一层类型检查
真正麻烦的不是怎么写,而是你得提前知道字段里到底混了哪些类型——$convert 不会替你猜,它只按你写的规则硬转。所以调试时先用 .toArray() 或 Compass 查几个原始文档,比盲目加转换更省时间。











