mongoose.Query.getQuery()返回BSON类型ObjectID,序列化转字符串原因及转普通JS对象方法
问题解答
自动转换的原因
MongoDB的BSON ObjectID实例原型上内置了toJSON()方法,当执行JSON.stringify()时,JSON序列化逻辑会自动调用待序列化对象的toJSON()方法获取序列化值。ObjectID的toJSON()方法默认返回24位十六进制格式的id字符串,因此你执行JSON.parse(JSON.stringify(query))之后得到的_id属性就是字符串类型。
你示例中序列化后出现_user字段是查询条件本身的属性,和转换逻辑无关
转为普通JavaScript对象的方案
根据你的需求可以选择两种实现方式:
方案1:保留ObjectID实例的纯对象
如果你需要保留ObjectID的BSON实例类型,仅需要剥离外层对象的非自有属性得到纯JS对象,可以手动实现深拷贝逻辑:
const mongoose = require("mongoose"); const { ObjectId } = mongoose.Types; function toPlainObject(obj) { // 基础类型直接返回 if (obj === null || typeof obj !== "object") return obj; // 保留Date、ObjectId实例 if (obj instanceof Date || obj instanceof ObjectId) return obj; // 数组递归处理 if (Array.isArray(obj)) return obj.map(toPlainObject); // 普通对象遍历自有属性复制 const plain = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { plain[key] = toPlainObject(obj[key]); } } return plain; } // 使用 const query = this.getQuery(); const plainQuery = toPlainObject(query);
方案2:所有BSON类型转JS原生类型
如果你不需要保留BSON实例,希望所有BSON类型都转为JS原生类型(ObjectID转字符串、二进制转Base64等),有两种简单实现:
- 直接使用你当前的
JSON.parse(JSON.stringify(query))方案,该方案性能较好,适合不需要自定义转换规则的场景 - 如果需要自定义转换规则,可以使用bson库的EJSON工具:
const { EJSON } = require("bson"); const plainQuery = EJSON.deserialize(EJSON.serialize(query), { relaxed: true });
内容的提问来源于stack exchange,提问作者Jaswanth Palakuru
相关产品推荐
相关产品推荐

