Typescript环境下如何在Mongoose的Lean查询结果中获取_id字段
符合Mongoose + NestJS最佳实践的实现方案如下:
方案1:单Schema针对性配置(推荐)
- 首先在
@Schema装饰器中开启id虚拟字段配置,同时显式声明类型避免TS类型报错:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { Document, LeanDocument, ObjectId } from 'mongoose'; @Schema({ // 开启id虚拟属性,自动将_id转为字符串映射到id字段 id: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }) export class Group { @Prop({ required: true }) name: string; // 仅做TS类型声明,不会影响MongoDB自动生成_id的逻辑 _id: ObjectId; id: string; } export type GroupDocument = Group & Document; export const GroupSchema = SchemaFactory.createForClass(Group); // 预定义Lean查询返回的类型,后续直接使用即可 export type GroupLean = LeanDocument<Group>;
- 查询时调用
lean()方法传入virtuals: true参数,即可同时访问_id和id属性:
// 返回值自动推导为GroupLean类型 const group = await this.groupModel.findOne().lean({ virtuals: true }); // 正常访问两个属性 console.log(group._id) // 原生ObjectId类型 console.log(group.id) // 字符串格式的_id
方案2:全局配置默认开启Lean虚拟字段
如果所有业务查询都需要该特性,可配置全局默认规则,无需每次查询传参:
- 全局Mongoose注册时配置:
// app.module.ts中 MongooseModule.forRoot('你的MongoDB连接地址', { lean: { virtuals: true } })
- 也可针对单个Schema配置:
export const GroupSchema = SchemaFactory.createForClass(Group); GroupSchema.set('lean', { virtuals: true });
配置完成后直接调用lean()即可得到带_id和id的POJO对象:
const group = await this.groupModel.findOne().lean();
说明
该方案完全符合Mongoose官方最佳实践,不需要让实体类继承Document引入额外方法和开销,也不需要手动维护_id字段的生成逻辑,所有能力均由Mongoose原生提供。
内容的提问来源于stack exchange,提问作者QuickSort
相关产品推荐
相关产品推荐

