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

MongoDB/Mongoose查询如何提取ObjectId中的纯字符串ID值

Mongoose+TypeScript 提取_id纯字符串的正确方法

首先说明两个代码误区:

  • Model.findById() 入参直接接收文档ID字符串即可,不需要额外包装为{_id: id}格式的查询对象,多余的包装会导致查询逻辑异常、TS类型报错。
  • Mongoose默认返回的查询结果是Mongoose文档实例,其上的_id字段是ObjectId类型实例,并非字符串类型,直接取值会拿到带ObjectId包装的对象,需要调用内置转换方法才能拿到纯字符串ID。

可用实现方案

  • 方案1:调用ObjectId自带的toString()方法,适配所有场景
async findById(id: string) {
  // 直接传入id字符串查询
  const userDoc = await userModel.findById(id);
  // 调用toString()即可拿到"62aa4bddae588fb13e8df552"格式的纯字符串ID
  const pureId = userDoc?._id?.toString();
  // 后续直接使用pureId做存储、传参即可
  return pureId;
}
  • 方案2:使用Mongoose文档默认自带的id虚拟属性,写法更简洁
    Mongoose为所有文档实例默认挂载了id getter属性,直接取值就能得到_id对应的十六进制字符串,不需要手动调用转换方法:
async findById(id: string) {
  const userDoc = await userModel.findById(id);
  // 直接取id属性,就是纯字符串格式的文档ID
  const pureId = userDoc?.id;
  return pureId;
}
  • 方案3:全局配置Schema转换,查询直接返回_id为字符串的纯对象
    如果需要所有查询结果的_id默认就是字符串格式,可以在定义Schema时配置转换规则,查询时搭配lean()选项跳过Mongoose文档实例化,直接返回普通JS对象:
// 定义User Schema时添加全局转换配置
const userSchema = new Schema(
  {
    // 你的业务字段定义,比如username、age等
  },
  {
    toObject: {
      transform: (_, ret) => {
        ret._id = ret._id.toString();
        return ret;
      }
    },
    toJSON: {
      transform: (_, ret) => {
        ret._id = ret._id.toString();
        return ret;
      }
    }
  }
);

// 查询时加lean(),返回的普通对象中_id已经自动转为字符串
async findById(id: string) {
  const userDoc = await userModel.findById(id).lean();
  // 此处userDoc._id已经是纯字符串,不需要额外转换
  return userDoc;
}

TypeScript类型提示:如果使用全局转换+lean的方案,定义用户文档类型时直接将_id字段类型标注为string即可,避免类型校验报错。

内容的提问来源于stack exchange,提问作者Ali Corrales

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:42:13