【问题标题】: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 核心中得到解决。

标签: node.js mongodb mongoose


【解决方案1】:

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

请查看github项目:

您可以创建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 的猫鼬插件可以帮助实现此功能,它是最新的。

    【讨论】:

      猜你喜欢
      • 2020-12-16
      • 2013-10-21
      • 2017-03-13
      • 2015-10-11
      • 2013-07-15
      • 1970-01-01
      • 2016-02-07
      • 2019-04-25
      • 2015-11-27
      相关资源
      最近更新 更多