【问题标题】: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前的下划线)。

为什么代码有效?

【问题讨论】:

    标签: typescript mongodb mongoose nestjs


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2017-10-09
      • 2019-04-15
      • 2019-07-11
      • 2015-03-06
      • 2023-04-09
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多