$inc 专用于原子性字段增减,支持正负数及多字段同时更新,自动创建缺失字段;$add 配合 $set 实现字段表达式求和,需处理 null 和类型转换;$sum 仅用于聚合统计,不修改数据。

直接用 $inc,别绕路写聚合或脚本。 它专为字段原地加减设计,原子、高效、语义清晰。
用 $inc 更新单个字段值
这是最常见也最推荐的方式,适用于库存、积分、计数器等场景。它在服务端原子执行,避免读-改-写竞争。
-
$inc只接受数字(int、long、double),不支持字符串数字(如"123") - 负数即为“减法”:
{$inc: {score: -5}} - 可同时更新多个字段:
{$inc: {views: 1, likes: 1, score: 10}} - 如果字段不存在,
$inc会自动创建并设为操作数(如views从undefined变成1)
对多个字段求和后累加到新字段($add + $set)
当你要把已有字段(如 price 和 fee)相加,并存入一个新字段(如 total),不能用 $inc —— 它不支持表达式。必须走聚合式更新:
- 用
$set配合$add表达式:{$set: {total: {$add: ["$price", "$fee"]}}} -
$add参数必须是数组,且每个元素都得是有效表达式(字段引用用"$field",字面量直接写) - 注意:如果任一字段为
null或缺失,$add返回null;若想兜底,需配合$ifNull:{$add: [{$ifNull: ["$price", 0]}, {$ifNull: ["$fee", 0]}]} - 该操作只能在
updateOne/updateMany的更新体中使用,不是所有驱动都默认支持(Node.js 4.15+、Python PyMongo 4.0+ 已支持)
批量累加全部文档的某个字段($sum 在 $group 中)
这不是“更新”,而是“统计总和”。如果你只是想知道集合里 quantity 字段加起来多少,用 $sum 累加器:
- 必须配合
$group阶段,通常用_id: null表示全集:[{$group: {_id: null, total: {$sum: "$quantity"}}}] -
$sum自动跳过非数字值(null、字符串、对象等),不会报错 - 若字段完全不存在于任何文档中,
$sum返回0,不是null - 不能用
$sum直接更新字段——它只产出结果,不修改源数据
真正容易被忽略的是类型隐式转换:MongoDB 对 $add 和 $sum 的输入类型很敏感。比如字段存的是字符串 "10",$add 不会自动转成数字,直接报错或返回 null;必须先用 $toInt 或 $convert 显式转换,否则累加就断了。











