NestJS Mongoose 模式继承
Posted
技术标签:
【中文标题】NestJS Mongoose 模式继承【英文标题】:NestJS Mongoose Schema Inheritence 【发布时间】:2021-11-15 06:02:32 【问题描述】:我正在尝试在 NestJS 中继承 Mongoose Schemas 或 SchemaDefitions,但我运气不佳。 我这样做是为了可以共享基本和通用模式定义详细信息,例如虚拟('id')和随机数,我们已附加到每个实体。每个模式定义在 Mongo 中都应该有自己的集合,因此鉴别器不起作用。
我尝试通过以下不同的方式实现这一点
首先,我定义了以下基本架构定义:
base.schema.ts
import Prop, Schema, SchemaFactory from '@nestjs/mongoose';
import Document, Types from 'mongoose';
import TimeStamps from './timestamps.schema';
export type BaseDocument = BaseSchemaDefinition & Document;
@Schema(
toJSON:
virtuals: true,
transform: function (doc: any, ret: any)
delete ret._id;
delete ret.__v;
return ret;
,
,
)
export class BaseSchemaDefinition
@Prop(
type: Types.ObjectId,
required: true,
default: Types.ObjectId,
)
nonce: Types.ObjectId;
@Prop()
timestamps: TimeStamps;
然后我继承架构定义并创建架构,以便以后可以通过以下方式在我的服务和控制器中使用它:
person.schema.ts
import Prop, SchemaFactory from '@nestjs/mongoose';
import * as mongoose from 'mongoose';
import Document from 'mongoose';
import Address from './address.schema';
import BaseSchemaDefinition from './base.schema';
export type PersonDocument = PersonSchemaDefintion & Document;
export class PersonSchemaDefintion extends BaseSchemaDefinition
@Prop( required: true )
first_name: string;
@Prop( required: true )
last_name: string;
@Prop()
middle_name: string;
@Prop()
data_of_birth: Date;
@Prop( type: [ type: mongoose.Schema.Types.ObjectId, ref: 'Address' ] )
addresses: [Address];
const PersonSchema = SchemaFactory.createForClass(PersonSchemaDefintion);
PersonSchema.virtual('id').get(function (this: PersonDocument)
return this._id;
);
export PersonSchema ;
这导致只允许我创建和获取在 BaseSchemaDefinition 中定义的属性。
“时间戳”: “已删除”:空, “更新”:“2021-09-21T16:55:17.094Z”, “创建”:“2021-09-21T16:55:17.094Z” , "_id": "614a0e75eb6cb52aa0ccd026", “随机数”:“614a0e75eb6cb52aa0ccd028”, "__v": 0
其次,我然后尝试使用这里描述的方法来实现继承 Inheriting Mongoose schemas(不同的 MongoDB 集合)
base.schema.ts
import Prop, Schema, SchemaFactory from '@nestjs/mongoose';
import Document, Types from 'mongoose';
import TimeStamps from './timestamps.schema';
export type BaseDocument = BaseSchemaDefinition & Document;
@Schema(
toJSON:
virtuals: true,
transform: function (doc: any, ret: any)
delete ret._id;
delete ret.__v;
return ret;
,
,
)
export class BaseSchemaDefinition
@Prop(
type: Types.ObjectId,
required: true,
default: Types.ObjectId,
)
nonce: Types.ObjectId;
@Prop()
timestamps: TimeStamps;
const BaseSchema = SchemaFactory.createForClass(BaseSchemaDefinition);
BaseSchema.virtual('id').get(function (this: BaseDocument)
return this._id;
);
export BaseSchema ;
person.schema.ts
import Prop from '@nestjs/mongoose';
import * as mongoose from 'mongoose';
import Document from 'mongoose';
import Address from './address.schema';
import BaseSchema, BaseSchemaDefinition from './base.schema';
export type PersonDocument = PersonSchemaDefintion & Document;
export class PersonSchemaDefintion extends BaseSchemaDefinition
@Prop( required: true )
first_name: string;
@Prop( required: true )
last_name: string;
@Prop()
middle_name: string;
@Prop()
data_of_birth: Date;
@Prop( type: [ type: mongoose.Schema.Types.ObjectId, ref: 'Address' ] )
addresses: [Address];
export const PersonSchema = Object.assign(
,
BaseSchema.obj,
PersonSchemaDefintion,
);
产生相同的输出。不知道为什么没有继承
以下是使用模式和构建模型的服务代码
person.service.ts
import Model from 'mongoose';
import Injectable from '@nestjs/common';
import InjectModel from '@nestjs/mongoose';
import
PersonSchemaDefintion,
PersonDocument,
from 'src/schemas/person.schema';
import TimeStamps from 'src/schemas/timestamps.schema';
@Injectable()
export class PersonService
constructor(
@InjectModel(PersonSchemaDefintion.name)
private personModel: Model<PersonDocument>,
)
async create(
personModel: PersonSchemaDefintion,
): Promise<PersonSchemaDefintion>
personModel.timestamps = new TimeStamps();
const createdPerson = new this.personModel(personModel);
return createdPerson.save();
async update(
id: string,
changes: Partial<PersonSchemaDefintion>,
): Promise<PersonSchemaDefintion>
const existingPerson = this.personModel
.findByIdAndUpdate(id, changes)
.exec()
.then(() =>
return this.personModel.findById(id);
);
if (!existingPerson)
throw Error('Id does not exist');
return existingPerson;
async findAll(): Promise<PersonSchemaDefintion[]>
return this.personModel.find().exec();
async findOne(id: string): Promise<PersonSchemaDefintion>
return this.personModel.findById(id).exec();
async delete(id: string): Promise<string>
return this.personModel.deleteOne( _id: id ).then(() =>
return Promise.resolve(`$id has been deleted`);
);
如果需要,我可以提供更多详细信息
【问题讨论】:
【参考方案1】:在摆弄了一段时间后,我发现了在利用这些技术时似乎可行的正确组合
这是基类
base.schema.ts
import Prop, Schema from '@nestjs/mongoose';
import Document, Types from 'mongoose';
import TimeStamps from './timestamps.schema';
export type BaseDocument = Base & Document;
@Schema()
export class Base
@Prop(
type: Types.ObjectId,
required: true,
default: Types.ObjectId,
)
nonce: Types.ObjectId;
@Prop()
timestamps: TimeStamps;
这里是继承base.schema的类
person.schema.ts
import Prop, Schema, SchemaFactory from '@nestjs/mongoose';
import Document, Types from 'mongoose';
import Address from './address.schema';
import Base from './base.schema';
export type PersonDocument = Person & Document;
@Schema(
toJSON:
virtuals: true,
transform: function (doc: any, ret: any)
delete ret._id;
delete ret.__v;
return ret;
,
,
)
export class Person extends Base
@Prop( required: true )
first_name: string;
@Prop( required: true )
last_name: string;
@Prop()
middle_name: string;
@Prop()
data_of_birth: Date;
@Prop( type: [ type: Types.ObjectId, ref: 'Address' ] )
addresses: [Address];
const PersonSchema = SchemaFactory.createForClass(Person);
PersonSchema.virtual('id').get(function (this: PersonDocument)
return this._id;
);
export PersonSchema ;
我唯一想改进的是将 virtual('id') 移至基类。但是模式继承不起作用。此时,它只适用于模式定义。这至少让我朝着正确的方向前进。如果有人有办法改进这一点,请贡献。
【讨论】:
以上是关于NestJS Mongoose 模式继承的主要内容,如果未能解决你的问题,请参考以下文章
NestJS + Mongoose:如何测试 document(data).save()?
NestJs / Mongoose 在 Docker 撰写时无法建立 MongoDB 数据库连接
mongoose @prop() 装饰器类型:模式定义中的对象_NestJS
如何引用我试图保存在 nestjs/mongoose 中的模式?