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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:57:03