Mihaela
Mihaela

Reputation: 2502

Inheriting Mongoose schemas

I wanted to make a base 'Entity Schema', and other model entities would inherit from it. I did it, kinda, but then strange thing happened.

Those are my schemas:

File: https://github.com/mihaelamj/nodechat/blob/master/models/db/mongo/schemas.js

But in MongoDB, they are all saved in the same document store: 'entity models' not separate ones, like Messages, Users.. Did I get what was supposed to happen, but not what I wanted, separate stores? If so I will just make a basic JSON/object as entity and append the appropriate properties for each entity. Or is there a better way? Thanks.

Upvotes: 16

Views: 22413

Answers (3)

Adrian Moisa
Adrian Moisa

Reputation: 4343

Since ES6 this works as well:

var ImageSchema: Schema = new Schema({
    ...CommonMetadataSchema.obj,
    src: String,
    description: String,
});

Upvotes: 8

Do Async
Do Async

Reputation: 4284

If you want multiple overlapping models with different MongoDB collections, then you use this approach:

function extendSchema (Schema, definition, options) {
  return new mongoose.Schema(
    Object.assign({}, Schema.obj, definition),
    options
  );
}

Example

const extendSchema = require('mongoose-extend-schema');

const UserSchema = new mongoose.Schema({
  firstname: {type: String},
  lastname: {type: String}
});

const ClientSchema = extendSchema(UserSchema, {
  phone: {type: String, required: true}
});

You simply extend the original object the schema was created with and recreate a new schema on its basis. This is some sort of abstract schema which you inherit from.

Check this npm module: https://www.npmjs.com/package/mongoose-extend-schema

Upvotes: 11

zangw
zangw

Reputation: 48346

Discriminators are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection. rather than different documents. It seems that you misunderstand the discriminators of mongoose. Here is one article could help you to catch it correctly.

Guide to mongoose discriminators


Here are some codes sample to meet your requirement, to save the derived schema as separated documents

function AbstractEntitySchema() {   
    //call super        
    Schema.apply(this, arguments);     
    //add                                     
    this.add({                              
        entityName: {type: String, required: false},
        timestamp: {type: Date, default: Date.now},
        index: {type: Number, required: false},
        objectID: {type: String},
        id: {type: String}
    });                                     
};
util.inherits(AbstractEntitySchema, Schema);

//Message Schema
var MessageSchema = new AbstractEntitySchema();
MessageSchema.add({
    text: {type: String, required: true},
    author: {type: String, required: true},
    type: {type: String, required: false}
});

//Room Schema
var RoomSchema = new AbstractEntitySchema();
RoomSchema.add({
    name: {type: String, required: true},
    author: {type: String, required: false},
    messages : [MessageSchema],
});

var Message = mongoose.model('Message', MessageSchema);
var Room = mongoose.model('Room', RoomSchema);

// save data to Message and Room

var aMessage = new Message({
     entityName: 'message',
     text: 'Hello',
     author: 'mmj',
     type: 'article'
    });

 var aRoom = new Room({
     entityName: 'room',
     name: 'Room1',
     author: 'mmj',
     type: 'article'
 });

 aRoom.save(function(err, myRoom) { 
    if (err)
        console.log(err);
    else                                  
        console.log("room is saved"); 
 });

 aMessage.save(function(err) {
    if (err)
        console.log(err);
    else
        console.log('user is saved');
 });

Upvotes: 14

Related Questions