猫鼬和打字稿如何自动将'_id'转换为'id'?
How does mongoose and typescript convert '_id' to 'id' automatically?
我正在使用 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 ;
}
然后另一个 class 使用该模型,如下所示:
@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前有下划线)。
为什么代码有效?
Moongose's Schemas add a virtual getter id
by default 并且可以关闭。
这是链接函数的 source code(自 v6.0.12 起),在给定特定 Schema
:
实例化 Model
时调用该链接函数
'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 函数的模式中,returns 属性 _id
转换为String
我正在使用 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 ;
}
然后另一个 class 使用该模型,如下所示:
@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前有下划线)。
为什么代码有效?
Moongose's Schemas add a virtual getter id
by default 并且可以关闭。
这是链接函数的 source code(自 v6.0.12 起),在给定特定 Schema
:
Model
时调用该链接函数
'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 函数的模式中,returns 属性 _id
转换为String