discord.js v14中MongoDB存储Discord用户ID失真问题求助
问题原因与解决方案
为什么ID会失真?
Discord用户ID是雪花算法(Snowflake)生成的64位整数,而JavaScript里的Number类型是64位浮点数,它只能精确表示到2^53 - 1(也就是9007199254740991)。当数值超过这个范围时,浮点数无法精确存储所有位数,会自动对末尾的数字进行近似处理——你遇到的358262932791885824被存成358262932791885800,本质就是精度丢失导致的四舍五入。
怎么解决?
核心思路是把Discord ID作为字符串存储,字符串不会有精度限制,能完整保留ID的每一位数字。
1. 修改Mongoose Schema
把discord_id的类型从Number改成String:
const mongoose = require('mongoose') const user = new mongoose.Schema({ discord_id: { type: String, // 这里从Number改为String unique: true, required: true }, xp: { type: Number, default: 0, required: true }, level: { type: Number, default: 0, required: true }, money: { type: Number, default: 0, required: true }, inventory: { type: Array, default: [], required: true }, daily: { last: { type: Number, default: 0, required: true }, next: { type: Number, default: 0, required: true } }, warnings: { adWarn: { type: Number, default: 0, required: true }, } }); module.exports = mongoose.model('user', user)
2. 存储逻辑无需额外修改
message.author.id本身就是字符串类型,所以你的用户初始化代码直接用就行,Mongoose会按照Schema定义把它存为字符串:
let kontrol = await user.findOne({discord_id: message.author.id}); if (!kontrol) { let newUser = new user({ discord_id: message.author.id, // 本身就是字符串,无需转换 xp: 0, level: 0, money: 0, inventory: [], daily: { last: 0, next: 0 }, warnings: { adWarn: 0 } }) await newUser.save(); }
3. 修正已有的失真数据
如果数据库里已经存了错误的ID,需要手动修正:
- 通过用户的用户名+判别器找到真实ID,然后更新数据库对应的
discord_id字段; - 或者删除原有错误数据,让用户重新触发初始化逻辑(比如发送一条消息),避免唯一键冲突。
这样修改后,数据库里的ID会和Discord真实ID完全一致,用这个ID查找用户就不会有问题了。
内容的提问来源于stack exchange,提问作者Grkm
相关产品推荐
相关产品推荐

