40

I wanted to use more than one schema per collection in mongodb , how to use it....?
It gives me this error when I try to run it:

Error:

OverwriteModelError: Cannot overwrite allUsers model once compiled.
OverwriteModelError: Cannot overwrite checkInOut model once compiled.


Heres my schema.js

   var mongoose = require('mongoose');

      var Schema = mongoose.Schema
          , ObjectId = Schema.ObjectId;

   var checkInInfoSchema= new Schema({
       name:String,
       loginSerialId:Number
   });


   var loginUserSchema = new Schema({
          sn : { type: Number, unique:true }
          ,uname: {type:String, unique:true}
          ,pass:String
      });

   var registerUserSchema = new Schema({
       sn : { type: Number, unique:true }
       , name: String   //his/her name
       ,pass:String,
       companyKey:{type:String},
       uname:{type:String,unique:true}
   });



   var checkInOutSchema = new Schema({
       uname: String
       ,companyKey:String
       ,task:String
       ,inTime:String
       ,outTime:String
       ,date:{type:String}
       ,serialId:{type:Number,unique:true}
       ,online:Boolean
   });

   //Different schema for same collection "allUsers"        
   var allUser=mongoose.model('allUsers',loginUserSchema);        
   var registerUser=mongoose.model('allUsers',registerUserSchema);

    //Different schema for same collection "checkInOut"
   var checkInOut=mongoose.model('checkInOut',checkInOutSchema);
   var checkInInfo=mongoose.model('checkInOut',checkInInfoSchema);

   module.exports={

       allUser:allUser, 
       registerUser:registerUser,

       checkInOut:checkInOut,
       checkInInfo:checkInInfo
   };
Community
  • 1
  • 1
TaLha Khan
  • 2,413
  • 2
  • 25
  • 39

3 Answers3

69

In mongoose you can do something like this:

var users = mongoose.model('User', loginUserSchema, 'users');
var registerUser = mongoose.model('Registered', registerUserSchema, 'users');

This two schemas will save on the 'users' collection.

For more information you can refer to the documentation: http://mongoosejs.com/docs/api.html#index_Mongoose-model or you can see the following gist it might help.

Julián Duque
  • 9,407
  • 1
  • 21
  • 16
  • 3
    I was giving them same names and didnt know that the name of collection is expected in 3rd parameter. – TaLha Khan Jan 22 '13 at 08:21
  • Any suggestion how to do methods for searching object of BOTH schemas? for example, I want to find both users and registered users and sort that by date, using just query. – Leg0 Dec 21 '13 at 22:13
  • 1
    Leg0, what does jQuery have to do with this? – bluehallu Mar 24 '14 at 14:44
  • this answer works for me but i am having trouble in view model is that while showing list of data it retrieves data of both schema. I want to show the data of schema in different list without repeating it on other list?? can u help please – Amit singh Jul 13 '15 at 06:03
  • I think this works in terms of saving, but since its still technically a different mongoose model, how do you do a query on the entire collection which would run both users & registeredUsers? – Khaled Osman Jul 12 '19 at 09:19
17

I tried the selected answer but when querying on specific model object, it retrieves data of both schemas. So I think using discriminator yields better solution:

const coordinateSchema = new Schema({
    lat: String,
    longt: String,
    name: String
}, {collection: 'WeatherCollection'});

const windSchema = new Schema({
   windGust: String,
   windDirection: String,
   windSpeed: String
}, {collection: 'WeatherCollection'});

//Then define discriminator field for schemas:
const baseOptions = {
    discriminatorKey: '__type',
    collection: 'WeatherCollection'
};

//Define base model, then define other model objects based on this model:
const Base = mongoose.model('Base', new Schema({}, baseOptions));
const CoordinateModel = Base.discriminator('CoordinateModel', coordinateSchema);
const WindModel = Base.discriminator('WindModel', windSchema);

//Query normally and you get result of specific schema you are querying:
mongoose.model('CoordinateModel').find({}).then((a)=>console.log(a));

Example output:

{ __type: 'CoordinateModel', // discriminator field
    _id: 5adddf0367742840b00990f8,
    lat: '40',
    longt: '20',
    name: 'coordsOfHome',
    __v: 0 },
sarah
  • 580
  • 1
  • 6
  • 24
0

When no collection argument is passed, Mongoose uses the model name. If you don't like this behavior, either pass a collection name, use mongoose.pluralize(), or set your schemas collection name option.

const schema = new Schema({ name: String }, { collection: 'actor' });

// or

schema.set('collection', 'actor');

// or

const collectionName = 'actor'
const M = mongoose.model('Actor', schema, collectionName)