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
相关产品推荐
相关产品推荐

