You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose中如何使用findByIdAndUpdate累加数据而非全量覆盖

问题场景

当前定义的Message Mongoose模型Schema如下:

var Message = mongoose.model('Message', {
    name: String,
    message: String,
    votes: Number
})

现有投票更新接口代码:

app.put('/messages/:id', (req, res) => {
    Message.findByIdAndUpdate({_id: req.params.id}, {votes: req.body.votes}).then(function(message){
        res.send(message)
    })
})

现有逻辑会直接用请求传入的votes值覆盖库中原有值:比如原有投票数为1、请求传入值为5时,最终votes会被更新为5,无法实现「在原有投票数基础上累加传入值、最终得到6票」的需求。

解决方案

使用MongoDB原生的$inc原子更新操作符即可实现数值累加,该操作在数据库层面原子执行,不需要先查询文档手动计算,并发场景下也不会出现计数不准的问题。
修改后的代码如下:

app.put('/messages/:id', (req, res) => {
    Message.findByIdAndUpdate(
        req.params.id, // findByIdAndUpdate第一个参数直接传id字符串即可,无需额外包装查询对象
        { $inc: { votes: req.body.votes } }, // $inc用于数字字段增减,传正数累加、传负数扣减
        { new: true } // 加该配置会返回更新后的最新文档,默认配置返回的是更新前的旧文档
    ).then(function(message){
        res.send(message)
    })
})

注意事项

  • 不要使用「先查询文档拿到旧votes值→手动相加计算新值→再save保存」的写法,并发请求下会出现计数覆盖、结果丢失的问题,$inc原子更新可以完全规避这个坑。
  • 如果后续需要实现取消投票、扣减票数的逻辑,直接给$inc传入对应的负数值即可,不需要调整更新逻辑。

内容的提问来源于stack exchange,提问作者albert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:45:48