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

Mongoose如何不新建数据库对象 实现同用户数据更新而非新增

问题根源

你当前的逻辑每次触发指令都会生成全新的_id,实例化一个全新的User模型后调用save(),Mongoose对带未入库新_id的模型实例会直接执行插入操作,必然生成新文档。同时你的Schema没有给userID加唯一约束,从数据库层面也无法阻止同一用户对应多条记录的问题。

修复步骤

1. 调整Schema定义

移除手动强制要求_id传入的配置,给userID字段加唯一索引,从结构上保证一个用户ID只对应一条记录:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;
const profileSchema = new Schema({
    userID: {
        type: String,
        required: true,
        unique: true
    },
    nickname: String,
});

module.exports = mongoose.model("User", profileSchema);

注意:如果你的数据库里之前已经存了同一userID的多条重复数据,先手动清理重复数据再重启服务,否则唯一索引会创建失败。Mongoose会在新文档创建时自动生成_id,不需要你手动调用mongoose.Types.ObjectId()生成。

2. 替换数据写入逻辑

放弃每次新建实例调用save()的写法,改用findOneAndUpdate配合upsert参数,实现「匹配到对应用户就更新昵称,匹配不到就自动新建记录」的逻辑:

const subregis = "!reg ign:";
client.on("message", async msg => {
  if (msg.content.includes(subregis)){ 
      const nickname = msg.content.substring(msg.content.indexOf(":") + 1).trim();
      try {
        await User.findOneAndUpdate(
          { userID: msg.author.id },
          { $set: { nickname: nickname } },
          { upsert: true, new: true }
        );
        msg.reply("Data has been submitted successfully") 
      } catch (err) {
        console.error(err);
        msg.reply("Save failed, please try again later")
      }
  }
});
参数说明
  • upsert: true:查询条件没有匹配到文档时,自动根据查询条件和更新内容创建新文档
  • new: true:返回更新完成后的文档内容,可选,如果你不需要拿到返回结果可以不加
  • 改成async/await写法是为了方便捕获错误,避免写入失败时还给用户返回提交成功的提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 16:48:18