5月29日 01:09

Mongoose 鉴别器 Discriminator 怎么用?

Discriminator 是 Mongoose 的单集合继承机制,通过 Event.discriminator('Conference', confSchema) 在同一集合中存储不同结构的文档,用 discriminatorKey 字段区分类型。所有鉴别器共享基础 Schema 的字段和索引,各自扩展独有字段,适合多态数据模型。

追问

discriminatorKey 的作用是什么? 它是 MongoDB 文档中用于标识类型的字段,默认叫 __t,可在基础 Schema 选项中自定义(如 kind、role)。创建鉴别器文档时自动写入,查询时 Mongoose 据此实例化正确的模型。

基础 Schema 的中间件会作用于鉴别器吗? 会。基础 Schema 的 pre/post 中间件对所有鉴别器生效,鉴别器自身的中间件只作用于该类型。利用这点可在基础 Schema 统一处理公共逻辑(如日志),鉴别器处理特有校验。

嵌套鉴别器怎么实现? 在子文档数组上调用 .discriminator():batchSchema.discriminator('ProductBatch', productBatchSchema),数组中的不同元素可以有不同的 Schema 结构,discriminatorKey 自动区分。

鉴别器有什么局限? 所有类型存在同一集合,无法对鉴别器特有字段建独立索引(索引会覆盖全集合);文档大小差异大时浪费存储;删除某类型文档需按 discriminatorKey 过滤;单集合数据量膨胀后影响所有类型的查询性能。

鉴别器适合哪些场景? 事件日志系统(Click/View/Purchase 共享时间戳基类)、内容管理(Article/Video/Image 共享标题和作者)、多角色用户(Admin/Customer 共享认证字段)。共同点:字段大量重叠、需要跨类型统一查询。

写段代码

javascript
const eventSchema = new Schema({ name: String, date: Date }, { discriminatorKey: 'kind' }); const Event = mongoose.model('Event', eventSchema); const Conf = Event.discriminator('Conf', new Schema({ speakers: [String] })); await Conf.create({ name: 'JSConf', date: new Date(), speakers: ['Tom'] }); // MongoDB: { kind: 'Conf', name: 'JSConf', ... }
标签:Mongoose