find后确定鉴别器类型的正确方法

Lon*_*Rob 3 mongoose node.js mongoose-schema

我想使用正确的猫鼬模型来表示具有多个鉴别器的文档。

\n\n

假设我有以下模型:

\n\n
const membershipSchema = mongoose.Schema({\n  name: { type: String, required: true },\n  course: { type: mongoose.Schema.Types.ObjectId, ref: 'Course' },\n  price: { type: Number, required: true, get: p => `\xc2\xa3${p}.00` }\n}, { discriminatorKey: 'type' });\n\nconst subscriptionSchema = mongoose.Schema({\n  frequency: {\n    type: String, enum: [ 'week' , 'month' ],\n    required: true, get: val => `${val}ly subscription` }\n})\n\nconst ticketSchema = mongoose.Schema({\n  frequency: { type: String, default: 'one-off' }\n});\n\nconst Membership = mongoose.model('Membership', membershipSchema);\nconst Subscription = Membership.discriminator('Subscription', subscriptionSchema);\nconst Ticket = Membership.discriminator('Ticket', ticketSchema);\n\nmodule.exports = { Membership, Ticket, Subscription };\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我有.find一组 时memberships,我事先并不知道它们是tickets 还是subscriptions。

\n\n

我目前正在执行类似的操作来查找特定用户的订阅:

\n\n
  const { Membership, Subscription, Ticket } = require('./membership');      \n  return Membership.find({ user: this._id });\n
Run Code Online (Sandbox Code Playgroud)\n\n

但该Membership模型没有正确的吸气剂,这些吸气剂是在鉴别器Subscription和上指定的Ticket

\n\n

我知道我有钥匙type告诉我某个特定文档是订阅还是票证。

\n\n

但是让每个文档用正确的模型表示的正确方法是什么?

\n

Lon*_*Rob 7

我已经用困难的方式解决了这个问题,但这不是正确的方法。在没有任何文档提供帮助的情况下,必须采用这种方式:

  const { Subscription, Ticket } = require('./membership');
  return Promise.all([
    // Find each type of discriminator in turn
    Subscription.find({ course: this._id }),
    Ticket.find({ course: this._id }),
  ]).then(membershipArray =>
    // Combine the resulting arrays into a single result array
    membershipArray.reduce((combined, array) => combined.concat(array), [])
  );
Run Code Online (Sandbox Code Playgroud)

欢迎改进/建议。


更新

猫鼬 API 可用model.discriminators,尽管这似乎完全没有记录。

我们可以使用它来调用find()每个鉴别器map

const discriminators = Membership.discriminators;

return Promise.all(Object.keys(discriminators).map(i => discriminators[i].find({ course: this._id }))
).then(promiseResults =>
  promiseResults.reduce((arr, el) => arr.concat(el), [])
);
Run Code Online (Sandbox Code Playgroud)

这是一种每次都能获得正确鉴别器的相当简单的方法,假设没有任何文档是针对父模型存储的。

如果是,则discriminators在运行该Promise.all行之前将父模型附加到对象是相当简单的。