discord.js结合MongoDB实现消息计数时messageCount字段无法创建
消息计数功能数据库写入失败问题排查
相关代码
message-counter.js
const mongo = require("mongoose") const schema = require("./schemas/rank/message-count-schema") module.exports = client => { client.on('messageCreate', async (message) => { const { author } = message const { id } = author mongo.connect( process.env.MONGO_URI, { keepAlive: true } ) const dataQuery = await schema.findOne({ _id: id }) if (!dataQuery) { const newSchem = schema( { _id: id }, { $setOnInsert: { messageCount: 1 } }, { $inc: { messageCount: 1 } }, { upsert: true } ) await newSchem.save() } else { dataQuery.updateOne( { $inc: { messageCount: 1 } }, { upsert: true } ) } }) }
message-count-schema.js
const mongoose = require('mongoose'); const messageCountSchema = new mongoose.Schema({ _id: { type: String, required: true }, messageCount: { type: Number, required: true } }) module.exports = mongoose.model('message-count', messageCountSchema);
运行效果参考

错误点与修复方向
- 数据库连接位置错误:
mongo.connect()被写在messageCreate事件回调内部,每次收到消息都会重复发起连接,且没有await等待连接完成就执行后续查询写入,操作执行时连接大概率未就绪。修复方向:将MongoDB连接逻辑移到机器人初始化阶段,全局只连接一次,确认连接成功后再注册事件监听。 - Mongoose模型实例化参数错误:给模型构造函数
schema()传入了$setOnInsert、$inc、upsert这类更新操作符配置,模型构造函数仅接收文档字段键值对,不识别更新操作符,会导致新生成的文档实例仅包含_id字段,缺失必填的messageCount字段,save()操作会触发校验失败无法写入。修复方向:创建新文档时仅传入实际字段值,不要混入更新操作符;如果要实现upsert(不存在则创建、存在则更新)逻辑,直接调用模型的静态更新方法(如findOneAndUpdate),不要手动拆分「查询-判断-创建/更新」分支。 - 更新操作缺少异步等待:已存在用户数据的分支中,调用
dataQuery.updateOne()时没有加await,该方法返回的Promise没有被等待,更新逻辑会在执行完成前被终止,无法写入数据库。 - 并发竞态风险:现有分两步的查询写入逻辑在高并发场景(短时间收到同一用户多条消息)下,会出现多次查询到数据不存在、重复创建文档的问题,可通过单条带upsert配置的原子更新语句替代现有分支逻辑解决。
内容的提问来源于stack exchange,提问作者IDcLuc
相关产品推荐
相关产品推荐

