如何为单个MongoDB集合配置多个Mongoose Schema?NestJS实现疑问
同一MongoDB集合使用多Mongoose Schema实现用户分类存储方案
你当前的问题在于NestJS模块中重复注册了同名的Member Model,这会导致Schema被覆盖,无法实现单集合多Schema的需求。正确的实现方式是利用Mongoose的**鉴别器(Discriminator)**功能,它支持在同一集合中存储不同类型的文档,通过指定的鉴别字段区分数据类型。
实现步骤
1. 定义基础用户Schema
先创建通用的基础用户Schema,包含两类用户共有的字段,并指定鉴别器键(用于区分普通用户和子用户):
// member.schema.ts import * as mongoose from 'mongoose'; export const MemberSchema = new mongoose.Schema({ first_name: { type: String, required: true }, last_name: { type: String, required: true }, userName: { type: String, unique: true, required: true }, email: { type: String, unique: true, required: true }, password: { type: String, required: true }, type: { type: String, default: 'member' }, // 鉴别器字段,默认标记为普通用户 adhar: { type: String, required: true }, is_active: { type: Boolean, default: true } }, { timestamps: true, discriminatorKey: 'type' // 指定鉴别器键为type字段 });
2. 创建子用户鉴别器Schema
基于基础Schema创建子用户的鉴别器Schema,只需添加子用户独有的扩展字段,无需重复定义通用字段:
// arya.schema.ts import * as mongoose from 'mongoose'; import { MemberSchema } from './member.schema'; // 仅定义子用户特有的字段 export const AryaSchema = MemberSchema.discriminator( 'subadmin', // 鉴别器名称,对应type字段的值 new mongoose.Schema({ higher_education: { type: String }, total_experience: { type: String } }, { timestamps: true }) );
3. 修改NestJS模块配置
模块中只需注册基础Schema,鉴别器会自动关联到同一集合,无需重复注册同名Model:
// member.module.ts @Module({ imports: [ MongooseModule.forFeature([ { name: 'Member', schema: MemberSchema } // 仅注册基础Schema ]), MemberAddressModule ], providers: [MemberService, AuthService, JwtStrategy, AryaService], controllers: [authController, AryaController] }) export class MemberModule {}
4. 在Service中使用鉴别器
- 普通用户操作:直接注入基础
MemberModel即可 - 子用户操作:通过基础Model获取鉴别器Model进行读写
示例AryaService代码:
// arya.service.ts import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { Member } from './member.interface'; import { Arya } from './arya.interface'; @Injectable() export class AryaService { private readonly aryaModel: Model<Arya>; constructor(@InjectModel('Member') private readonly memberModel: Model<Member>) { // 获取子用户鉴别器Model this.aryaModel = this.memberModel.discriminator<Arya>('subadmin'); } // 创建子用户 async createArya(userData: Partial<Arya>): Promise<Arya> { const arya = new this.aryaModel(userData); return arya.save(); } // 查询所有子用户 async findAllSubadmins(): Promise<Arya[]> { return this.aryaModel.find().exec(); } }
关键注意事项
- 鉴别器字段:通过
discriminatorKey指定的字段(如示例中的type)会自动标记文档类型,子用户的type值会被设为鉴别器名称(如subadmin) - 唯一索引:
userName、email等唯一索引会作用于整个集合,确保两类用户的这些字段不重复 - 避免重复注册:模块中不能重复注册同名Model,否则会导致Schema覆盖
内容的提问来源于stack exchange,提问作者jaswant patel
相关产品推荐
相关产品推荐

