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

Mongoose传入正确Discord ID调用findOne返回null问题求助

问题根源
  • 你使用的18位Discord ID数值(707876147324518400)已经超出JavaScript Number类型的最大安全整数范围(2^53-1 = 9007199254740991),直接传入数字字面量查询时,JS会自动丢失精度,导致实际查询的_id值和数据库中存储的目标值不匹配,因此返回null。
  • 无参数查询可以正常返回是因为该场景不需要进行查询值匹配,返回的文档中_id显示的数值只是JS精度丢失后的近似值,和数据库中实际存储的64位整数并不完全一致。
解决方案

方案1:修改数据存储类型(推荐)

该方案从根源避免跨语言数值精度问题,适合可以修改现有数据库数据的场景:

  1. 将集合中所有文档的_id从数值类型改为字符串类型,Discord ID原生为字符串格式的雪花ID,存为字符串不会有任何业务问题
  2. 修改Schema中_id的类型定义:
_id: String,
  1. 查询时传入字符串形式的ID即可:
anifarm.findOne({ _id: "707876147324518400" });

方案2:兼容现有数值存储

如果无法修改现有数据库数据,可通过mongoose支持64位整数解决:

  1. 安装mongoose-long依赖处理64位整数:
npm install mongoose-long
  1. 修改Schema配置,将_id类型声明为Long:
const mongoose = require('mongoose');
const Long = require('mongoose-long')(mongoose);

module.exports = mongoose.model('anifarm', new mongoose.Schema({
        _id: Long,
        // 其余字段保持原有配置不变
    },
    {
        collection: 'anifarm',
        versionKey: false
    })
);
  1. 查询时将字符串形式的ID转为Long类型再传入:
anifarm.findOne({ _id: mongoose.Types.Long.fromString("707876147324518400") });
验证方法

你可以直接在MongoDB Shell中执行以下命令验证问题:

  1. 直接用数值查询,会因为精度问题返回空:
db.anifarm.find({_id: 707876147324518400})
  1. 用NumberLong包裹字符串ID查询,可正常返回目标文档:
db.anifarm.find({_id: NumberLong("707876147324518400")})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:24:02