$concat拼接字符串时遇null必报错,须先用$ifNull处理空值;非字符串字段需$toString转换;update中需用pipeline语法才能使用$concat。

用 $concat 拼接字符串字段时,空值会直接报错
MongoDB 的 $concat 不接受 null 或缺失字段,只要任一参数是 null,整个聚合就会抛出 "$concat only supports strings, not null" 错误。这不是类型转换问题,而是硬性限制。
- 常见错误现象:
{ $concat: ["$first_name", " ", "$last_name"] }在last_name为null时失败 - 必须先处理空值,再拼接;不能指望
$concat自动跳过或忽略 - 推荐组合使用
$ifNull:它只在字段为null或缺失时生效,对空字符串""不触发 - 示例(安全拼接):
{ $concat: [{ $ifNull: ["$first_name", ""] }, " ", { $ifNull: ["$last_name", ""] }] }
$ifNull 的默认值不是万能兜底,要注意字段存在性与类型
$ifNull 只检查字段是否为 null 或根本不存在(undefined),但对 ""、0、false 这类“falsy”值完全无感——它们会被原样传入 $concat。
- 如果业务中字段可能存空字符串,需提前用
$cond+$eq判断,例如:{ $cond: [{ $eq: ["$middle_name", ""] }, "", "$middle_name"] } -
$ifNull第二个参数支持任意表达式,不只是字面量;可以嵌套$toString防止数字字段报错 - 性能影响极小,但嵌套过深(如多层
$ifNull套$cond)会让 pipeline 可读性骤降,建议拆成$addFields预处理
聚合阶段里拼接字符串,别漏掉 $toString 转换非字符串字段
数据库里经常混着存数字、日期、ObjectId,而 $concat 只认字符串。直接拼接 "$age" 或 "$created_at" 会立刻报错。
- 必须显式转类型:
{ $toString: "$age" }、{ $dateToString: { format: "%Y-%m", date: "$created_at" } } -
$toString对null返回null,所以仍需配合$ifNull——顺序很重要:先$ifNull再$toString,否则null进$toString还是null - ObjectId 转字符串用
{ $toString: "$_id" }即可,不用$oid等旧语法
更新操作(updateOne / updateMany)里不能直接用 $concat
很多人想在 update 中动态拼接并写入新字段,但 MongoDB 的 update 表达式($set)不支持 $concat 等聚合操作符——除非用带 pipeline 的 update 语法(4.2+)。
- 普通
$set: { full_name: { $concat: [...] } }会静默失败或报错"unknown operator: $concat" - 正确做法是用 pipeline update:
db.users.updateOne({ _id: 123 }, [ { $set: { full_name: { $concat: [...] } } } ]) - 注意:pipeline update 不支持
upsert: true与数组位置操作符(如$[])混用,容易踩坑
"" 和 null 的区别,以及更新语句里该用普通对象还是 pipeline 数组——这两个点一旦选错,要么没效果,要么报错还不好定位。

















