所以我有两个模式,文章和事件都有一个图像字段 .
对于文章,
featured_image: {
type: String,
default: '',
}
对于活动,
featured_image: {
type: Schema.ObjectId,
ref: 'Medium'
}
我有另一个架构,卡,像这样
type: {
type: String,
enum: ['Article', 'Event']
},
data: {
type: Schema.ObjectId,
refPath: 'type'
}
我正试图填充卡片,就像这样
Card
.find(query)
.populate({
path: 'data',
populate: [{
path: 'featured_image',
model: 'Medium',
select: 'source type'
}]
};)
但是,它一直给我一个强制转换错误,因为当卡片属于Event类型时,它会很好地填充,但是当它是“Article”类型时,feature_image字段是字符串类型,因此无法填充 .
如果card类型为Event或者它是引用id而不是string,我如何填充featured_image字段 .
1 回答
而不是你试图做的事情,你应该使用“鉴别器”,这实际上是处理对象类型在给定参考中变化的关系的正确方法 .
您可以通过定义模型的不同方式使用鉴别器,而不是使用“基本模型”和模式构建,如下所示:
因此,您可以在此处定义"base model",例如
Content
,您实际上将引用指向Event
.下一部分是不同的模式实际上通过基本模型中的
.discriminator()
方法注册到此模型,而不是.model()
方法 . 这将使模式与通用Content
模型一起注册,当您引用使用.discriminator()
定义的任何模型实例时,使用注册的模型名称在该数据中隐含存在特殊的__t
字段 .除了在不同类型上启用mongoose到
.populate()
之外,这还具有附加到不同类型的项目的"full schema"的优点 . 因此,如果您愿意,您可以使用不同的验证和其他方法 . 确实"polymorphism"在数据库上下文中工作,附加了有用的模式对象 .因此,我们可以演示已完成的各种"joins",以及您现在可以使用
Article
和Event
的单独模型,这些模型仅处理所有查询和操作中的那些项目 . 您不仅可以使用"individually",而且由于此机制实际上将数据存储在同一个集合中,因此还有一个Content
模型可以访问这两种类型 . 这实质上是主关系如何在Event
模式的定义中起作用 .As a full listing
And the sample output for different queries