mongoose 和 typescript 如何自动将 '_id' 转换为 'id'?

Posted

技术标签:

【中文标题】mongoose 和 typescript 如何自动将 \'_id\' 转换为 \'id\'?【英文标题】:How does mongoose and typescript convert '_id' to 'id' automatically?mongoose 和 typescript 如何自动将 '_id' 转换为 'id'? 【发布时间】:2021-12-19 17:04:31 【问题描述】:

我正在使用 NestJs (TypeScript) 和 mongoose 来持久化到 mongodb,我有一个这样的界面(在一个文件中):

import * as mg from 'mongoose' ; 

export const ProductSchema = new mg.Schema(
  
    title:  type : String, required: true, 
    description:  type : String, required: true, 
    price:  type: Number, required: true 

  
)
export interface Product
  title: string ;  
  description: string ; 
  price: number ;
  

然后使用模型的另一个类,像这样:

@Injectable()
export class ProductsService 
    private products: Product[] = [];

    constructor(
        @InjectModel('Product') private readonly productModel: Model<Product>
    )  ;

    async findProduct(prodId: string) 
        
        const product = await this.productModel.findById(prodId)

        if (!product) 
            console.log("product null")
            throw new NotFoundException('no product with that id');
        
   
        return  id: product.id, title: product.title, description: product.description, price: product.price ;

    

令人惊讶的是,在最后一个函数findProduct() 中,当我执行product.id(最后一行)时没有错误,并且代码可以神奇地运行。显然,我的Product模型中没有id字段,当然在mongodb中,id字段是_id(id前的下划线)。

为什么代码有效?

【问题讨论】:

【参考方案1】:

Moongose's Schemas add a virtual getter id by default 并且可以关闭。

这是在给定特定Schema 的情况下实例化Model 时调用的链接函数的source code(从v6.0.12 开始):

'use strict';

module.exports = function addIdGetter(schema) 
  // ensure the documents receive an id getter unless disabled
  const autoIdGetter = !schema.paths['id'] &&
    schema.paths['_id'] &&
    schema.options.id;
  if (!autoIdGetter) 
    return schema;
  

  schema.virtual('id').get(idGetter);

  return schema;
;

/*!
 * Returns this documents _id cast to a string.
 */

function idGetter() 
  if (this._id != null) 
    return String(this._id);
  

  return null;

我们可以看到它作为虚拟属性添加到架构中,并使用 getter 函数返回属性 _id 转换为 String

【讨论】:

以上是关于mongoose 和 typescript 如何自动将 '_id' 转换为 'id'?的主要内容,如果未能解决你的问题,请参考以下文章

mongoose 和 typescript 如何自动将 '_id' 转换为 'id'?

如何在 NestJs 和 typescript 中使用 `mongoose-delete` 插件?

graphql + mongoose + typescript,如何减少重复的模型定义

如何在 NodeJS、Mongoose 和 TypeScript 中使用日期和时间?

如何使用 Mongoose 和 Typescript 实现强类型静态模式函数?

如何在nestjs mongoose typescript中引用嵌套文档