如果我有一个模型
Attachment
,它可以分为4种类型:Link
、YoutubeVideo
、GoogleDriveFile
和GoogleDriveFolder
,我如何使用Mongoose将Attachment
区分为这些类型,以及允许它们成为另一个模式中的子文档; Post
?
我创建了基础
Attachment
模型,并使用判别器将其划分为单独的模型:
var AttachmentSchema = new Schema({
id: {type: String, required: true},
title: {type: String, required: true}
});
var Attachment = mongoose.model('Material', AttachmentSchema);
module.exports = {
DriveFile: Attachment.discriminator('GoogleDriveFile', new mongoose.Schema()),
DriveFolder: Attachment.discriminator('GoogleDriveFolder', new mongoose.Schema()),
Link: Attachment.discriminator('Link', new mongoose.Schema()),
YoutubeVideo: Attachment.discriminator('YoutubeVideo', new mongoose.Schema())
};
现在,在
Post
模式中,应该有一系列具有不同类型的附件:
var Attachment = require('./attachment');
var PostSchema = new Schema(
text:{type: String},
attachments: [Material] // Could be Material.Link, Material.YoutubeVideo, etc
});
当我这样做时,我收到一条错误消息“未定义类型
Model
at GoogleDriveFile
。您尝试过嵌套架构吗?您只能使用引用或数组进行嵌套。”
我不知道这个错误意味着什么,而且我找不到任何解释如何执行此操作的文档。帮忙吗?
尝试执行以下操作:
var AttachmentSchema = new Schema({
id: {type: String, required: true},
title: {type: String, required: true}
});
var PostSchema = new Schema({
text: { type: String },
attachments: [ AttachmentSchema ] // Could be Material.Link, Material.YoutubeVideo, etc
});
var attachmentArray = PostSchema.path('attachments');
module.exports = {
Post: mongoose.model('Post', PostSchema),
DriveFile: attachmentArray.discriminator('GoogleDriveFile', new mongoose.Schema({})),
DriveFolder: attachmentArray.discriminator('GoogleDriveFolder', new mongoose.Schema({})),
Link: attachmentArray.discriminator('Link', new mongoose.Schema({})),
YoutubeVideo: attachmentArray.discriminator('YoutubeVideo', new mongoose.Schema({}))
};
关键是不要使用猫鼬模型,使用父文档模式的 schema.path 作为鉴别器的基础。
在此链接上搜索术语 docArray:Mongoose Discriminator 文档
对于其他正在使用NestJS和
nestjs/mongoose
的人,以Scott Gnile的回答为参考,你可以这样做:
@Schema()
export class MainClass {
// some properties here
@Prop({ type: SubClass })
sub: SubClass;
}
export const MainClassSchema = SchemaFactory.createForClass(MainClass);
@Schema({ _id: false, discriminatorKey: 'kind' })
export class SubClass {
@Prop({ required: true, type: String, enum: Foo })
kind: string;
// Timestamp as an example for shared properties
@Prop({ default: Date.now })
timestamp: Date;
}
@Schema({ _id: false })
export class SubClassBar {
kind = Foo.Bar; // Set the discriminator to the correct value
// Add further props
}
export const SubClassBarSchema = SchemaFactory.createForClass(SubClassBar);
@Module({
imports: [
{ name: MainClass.name, schema: MainClassSchema },
{
name: SubClass.name,
schema: MainClassSchema.path('sub').schema, // notice the .schema
discriminators: [
{ name: Foo.Bar, schema: SubClassBarSchema },
// add further kinds here
]
}
]
})
export class MainModule { }