如何阻止MongoDB Node.js驱动将Long类型转换为Number类型?
解决MongoDB Node.js驱动自动将Long转为number的问题
问题重现
使用mongodb驱动(版本^4.13.0)时会出现不一致的类型返回行为:
- 存入较小的
Long值,查询返回时会被自动转为number类型:
// import { Long } from "mongodb"; await collection.insertOne({ test: Long.fromNumber(24), }); const rec = await collection.findOne({ test: Long.fromNumber(24) }, {}); if (rec === null) throw Error("not found"); console.log(typeof rec.test); // number console.log(rec.test);
- 仅当
Long值超出JavaScript安全整数范围时,查询结果才会返回Long对象:
await collection.insertOne({ test: Long.MAX_VALUE, }); const rec = await collection.findOne({ test: Long.MAX_VALUE }, {}); if (rec === null) throw Error("not found"); console.log(typeof rec.test); // object console.log(rec.test); // Long(...)
这种无文档说明的自动转换会增加结果处理的复杂度,想要统一返回Long类型可通过以下方式实现。
解决方案
在创建MongoDB客户端连接时,通过bsonOptions配置promoteLongs: false,就能禁用自动转换,让驱动始终返回Long对象。
示例代码:
import { MongoClient, Long } from "mongodb"; async function initMongo() { // 连接时配置BSON解析选项 const client = new MongoClient("mongodb://localhost:27017", { bsonOptions: { promoteLongs: false // 核心配置:禁止Long转number } }); await client.connect(); const db = client.db("your_db_name"); const collection = db.collection("your_collection_name"); // 测试插入与查询 await collection.insertOne({ test: Long.fromNumber(24) }); const rec = await collection.findOne({ test: Long.fromNumber(24) }); console.log(typeof rec.test); // object console.log(rec.test instanceof Long); // true } initMongo().catch(console.error);
原理说明
promoteLongs是MongoDB驱动的BSON解析默认选项,默认值为true:会将能安全转换为JavaScript number类型的BSON Long值自动转成number;设置为false后,所有BSON Long类型的值都会以Long对象形式返回,不受数值大小影响。
内容的提问来源于stack exchange,提问作者Jason Lee
相关产品推荐
相关产品推荐

