是否有可能在猫鼬中有一系列替代子文档模式

Posted

技术标签:

【中文标题】是否有可能在猫鼬中有一系列替代子文档模式【英文标题】:Is it possible to have an array of alternative subdocument schemas in mongoose 【发布时间】:2013-03-12 12:59:04 【问题描述】:

是否可以在 mongoose 中有一系列替代子文档模式?

例如,假设这个场景:如果我有一个人的主模式并且我有一个名为车辆类型数组的字段,我希望能够定义子文档模式,但是对于每种车辆类型(汽车、摩托车、自行车、公共汽车等):

var car = new mongoose.Schema(
    make:  type: String, required: true, default: 'Ford', trim: true ,
    model:  type: String, trim: true ,
    wheels: Number,
);
var motorbike = new mongoose.Schema(
    make:  type: String, required: true, default: 'Honda', trim: true ,
    model:  type: String, trim: true ,
    seats: Number,
);
var bike = new mongoose.Schema(
    make:  type: String, required: true, default: 'MuddyFox', trim: true ,
    model:  type: String, trim: true ,
    lights: Number,
);
var bus = new mongoose.Schema(
    make:  type: String, required: true, default: 'MAN', trim: true ,
    model:  type: String, trim: true ,
    dents: Number,
);

/* person */
var person = new mongoose.Schema(
    name:  type: String, required: true, default: 'Joe Bloggs', trim: true ,
    timeCreated:  type: Date, required: true, default: Date.now ,
    vehicles: [car, motorbike, bike, bus] /* this is what i want to do */
);

db.model('person', person);

注意人员架构。

因此该人可以拥有这些车辆中的任何一辆,但每辆车的数据仍会根据其自己的架构进行验证。

提前致谢

【问题讨论】:

我什至没有意识到在 SO 上发帖 2 个月后可能没有 cmets! 哇,这正是我一直在寻找的问题,但遗憾的是,没有人回答。你有想过吗? 很遗憾没有!我认为在任何情况下都不可能。对于每个子文档(车辆),您最好使用不同的集合,然后使用车辆数组来存储 _ids - 此外,我也会将所有者 _id 存储在每个车辆模式中。 我认为您可以通过手动验证来做到这一点,例如在pre('save') 感谢大家的贡献。这是一个重要的问题,看到 mongoose 通常如何抵消无模式数据库的优势,我希望这将在 mongoose 核心中得到解决。 【参考方案1】:

有一个名为 mongoose-schema-extend 的 mongoose 插件,它允许您为 Mongoose 启用 Schema Inheritance,基本上我认为,您正在寻找这个功能。

请查看github项目:

https://github.com/briankircho/mongoose-schema-extend

您可以创建Vehicle 架构,将其作为数组添加到Person 架构,并针对您不同类型的车辆扩展Vehicle

【讨论】:

【参考方案2】:

我找不到任何将多个嵌入文档作为数组传递的示例。

也许你可以这样调整:

var car = new mongoose.Schema(
    make:  type: String, required: true, default: 'Ford', trim: true ,
    model:  type: String, trim: true ,
    wheels: Number,
);
var motorbike = new mongoose.Schema(
    make:  type: String, required: true, default: 'Honda', trim: true ,
    model:  type: String, trim: true ,
    seats: Number,
);
var bike = new mongoose.Schema(
    make:  type: String, required: true, default: 'MuddyFox', trim: true ,
    model:  type: String, trim: true ,
    lights: Number,
);
var bus = new mongoose.Schema(
    make:  type: String, required: true, default: 'MAN', trim: true ,
    model:  type: String, trim: true ,
    dents: Number,
);

var transport = new mongoose.Schema(
    car: [car],
    motorbike: [motorbike],
    bike: [bike],
    bus: [bus]
);

/* person */
var person = new mongoose.Schema(
    name:  type: String, required: true, default: 'Joe Bloggs', trim: true ,
    timeCreated:  type: Date, required: true, default: Date.now ,
    vehicles: [transport]
);

db.model('person', person);

如果这不起作用,那么如this SO question 中所述,您可以使用mongoose populate。现在这种方法在添加deep population was added in Mongoose Deep 3.6之后更加有效。

所以你可以这样做:

var personSchema = Schema(
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [ type: Schema.Types.ObjectId, ref: 'Story' ]
);

var storySchema = Schema(
  _creator :  type: Number, ref: 'Person' ,
  title    : String,
  fans     : [ type: Number, ref: 'Person' ]
);

var Story  = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);

还有一个名为mongoose-deep-populate 的猫鼬插件可以帮助实现此功能,它是最新的。

【讨论】:

以上是关于是否有可能在猫鼬中有一系列替代子文档模式的主要内容,如果未能解决你的问题,请参考以下文章

在猫鼬中仅更改整个嵌入式文档数组的一个字段

在猫鼬中删除子文档

如何在猫鼬中找到最新的子文档

如何在猫鼬中填充另一个模型的子文档?

如何仅在猫鼬中获取子文档?

如何仅在猫鼬中获取子文档?