Mongoose: extending schemas

前端 未结 9 475
轮回少年
轮回少年 2020-12-05 10:10

Currently I have two almost identical schemas:

var userSchema = mongoose.Schema({

    email: {type: String, unique: true, required: true, validate: emailVal         


        
相关标签:
9条回答
  • 2020-12-05 10:41

    Mongoose 3.8.1 now has support for Discriminators. A sample, from here: http://mongoosejs.com/docs/api.html#model_Model.discriminator

    function BaseSchema() {
      Schema.apply(this, arguments);
    
      this.add({
        name: String,
        createdAt: Date
      });
    }
    util.inherits(BaseSchema, Schema);
    
    var PersonSchema = new BaseSchema();
    var BossSchema = new BaseSchema({ department: String });
    
    var Person = mongoose.model('Person', PersonSchema);
    var Boss = Person.discriminator('Boss', BossSchema);
    
    0 讨论(0)
  • 2020-12-05 10:41

    I didn't require discrimination, as I was trying to extend sub document schema's which are stored as a part of a parent document anyway.

    My solution was to append an "extend" method to the schema that is the base schema, so that you can either use the base schema itself or generate a new schema based on it.

    ES6 code follows:

    'use strict';
    
    //Dependencies
    let Schema = require('mongoose').Schema;
    
    //Schema generator
    function extendFooSchema(fields, _id = false) {
    
      //Extend default fields with given fields
      fields = Object.assign({
        foo: String,
        bar: String,
      }, fields || {});
    
      //Create schema
      let FooSchema = new Schema(fields, {_id});
    
      //Add methods/options and whatnot
      FooSchema.methods.bar = function() { ... };
    
      //Return
      return FooSchema;
    }
    
    //Create the base schema now
    let FooSchema = extendFooSchema(null, false);
    
    //Expose generator method
    FooSchema.extend = extendFooSchema;
    
    //Export schema
    module.exports = FooSchema;
    

    You can now use this schema as is, or "extend" it as needed:

    let BazSchema = FooSchema.extend({baz: Number});
    

    Extension in this case creates a brand new Schema definition.

    0 讨论(0)
  • 2020-12-05 10:48

    To add to this discussion, you can also override mongoose.Schema with a custom base schema definition. For code compatibility, add the if statement that allows a Schema to be instantiated without new. While this can be convenient, think twice before doing this in a public package.

    var Schema = mongoose.Schema;
    
    var BaseSyncSchema = function(obj, options) {
    
        if (!(this instanceof BaseSyncSchema))
            return new BaseSyncSchema(obj, options);
    
        Schema.apply(this, arguments);
    
        this.methods.update = function() {
            this.updated = new Date();
        };
    
        this.add({
            updated: Date
        });
    };
    util.inherits(BaseSyncSchema, Schema);
    
    // Edit!!!
    // mongoose.Schema = BaseSyncSchema; <-- Does not work in mongoose 4
    // Do this instead:
    Object.defineProperty(mongoose, "Schema", {
        value: BaseSyncSchema,
        writable: false
    });
    
    0 讨论(0)
提交回复
热议问题