使用MongoDB和discord.js存储Discord成员消息数出现CastError如何解决
问题排查与解决方案
报错的核心原因是操作数据库时,messages字段被传入了undefined值,不符合Schema定义的Number类型必填要求,导致Mongoose类型转换失败。你可以按以下步骤逐一修复:
1. 先修复消息监听代码的明显错误
你当前的消息监听代码里没有定义sender变量,获取用户ID的逻辑错误,同时注意discord.js v13及以上版本已废弃message事件,需改用messageCreate:
// 修正后的监听代码 client.on('messageCreate', async (message) => { // 建议把require放到文件顶部,不要放在事件回调里重复加载 const messageStuff = require('./messageCount') // 忽略机器人自身发送的消息,避免重复统计 if (message.author.bot) return const guildId = message.guild.id // 正确获取发消息的用户ID const userId = message.author.id const incMessage = await messageStuff.addMSG(guildId, userId, 1) })
2. 优化Schema定义,给数字字段添加默认值
新增用户文档时如果没有显式传入points和messages的值,Schema的默认值会自动填充,避免出现undefined的问题:
const mongoose = require('mongoose') const reqString = { type: String, required: true } const profileSchema = mongoose.Schema({ guildId: reqString, userId: reqString, points: { type: Number, required: true, default: 0 // 新增默认值 }, messages: { type: Number, required: true, default: 0 // 新增默认值 }, }) module.exports = mongoose.model('profiles', profileSchema)
3. 修正messageCount.js中addMSG方法的逻辑
绝大多数这类报错都是因为更新/新增文档的逻辑有问题,推荐直接用findOneAndUpdate结合upsert参数自动处理新老用户的统计逻辑,不用自己手动判断用户是否存在:
// messageCount.js 示例代码 const profileModel = require('./profileSchema') // 替换为你的schema实际路径 exports.addMSG = async (guildId, userId, addCount) => { return await profileModel.findOneAndUpdate( // 匹配条件:同服务器同用户 { guildId, userId }, // 增量更新逻辑 { $inc: { messages: addCount, points: 0 // 如果你有积分规则可以替换成对应增量值,暂时不需要就填0 } }, { new: true, // 返回更新后的最新文档 upsert: true, // 没有匹配到用户就自动创建新文档 setDefaultsOnInsert: true // 开启后新增文档会自动应用Schema里的默认值 } ) }
注意:setDefaultsOnInsert参数必须开启,否则upsert创建新文档时不会自动应用Schema的默认值
内容的提问来源于stack exchange,提问作者Slimey
相关产品推荐
相关产品推荐

