27

I have a common method for updating document of any collection in MongoDB?

The following code is in file name Deleter.js

module.exports.MongooseDelete = function (schemaObj, ModelObject);
{
  var ModelObj = new mongoose.Model("collectionName",schemaObj);
  ModelObj.remove(ModelObject);
}

And invoking as follows in my main file app.js:

var ModObj = mongoose.model("schemaName", schemasObj);
var Model_instance = new ModObj();
var deleter = require('Deleter.js');
deleter.MongooseDelete(schemasObj,Model_instance);

I am getting following error:

OverwriteModelError: Cannot overwrite `undefined` model once compiled.
    at Mongoose.model (D:\Projects\MyPrjct\node_modules\mongoose\lib\index.js:4:13)

I get on 2nd method call only.. Please let me know if any one has got some solution.

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
Amol M Kulkarni
  • 21,143
  • 34
  • 120
  • 164
  • 1
    What are you trying to do with `MongooseDelete`? Why not just call `Model_instance.remove();`? – JohnnyHK Feb 01 '13 at 13:48
  • I am just trying to make delete call a common method, in my custom module.. I works even if I call MongooseDelete(/*params*/) n times provided if the schema is same, When I try to delete document of different schema, I am getting above error message. Thanks for your kind interest in the answering... – Amol M Kulkarni Feb 04 '13 at 05:37
  • 1
    Couldn't you change `MongooseDelete` to just call `ModelObject.remove();`? – JohnnyHK Feb 04 '13 at 05:53
  • In 'MongooseDelete' I need 'ModelObject' to invoke 'remove()' method, and that 'ModelObject' should be created with particular schema. Thats the only reason I am passing 'SchemaObject' and 2ne 'ModelObject' with values (_id,etc..) – Amol M Kulkarni Feb 04 '13 at 06:28
  • You must not import the schema in two executing files, when your program loads then it finds two models and show overwrite message for the model. – Mohammad Waqas Feb 13 '21 at 02:20

8 Answers8

52

I managed to resolve the problem like this:

var Admin;

if (mongoose.models.Admin) {
  Admin = mongoose.model('Admin');
} else {
  Admin = mongoose.model('Admin', adminSchema);
}

module.exports = Admin;
paulbjensen
  • 828
  • 7
  • 6
36

I think you have instantiated mongoose.Model() on the same schema twice. You should have created each model only once and have a global object to get a hold of them when need

I assume you declare different models in different files under directory $YOURAPP/models/

$YOURAPPDIR/models/
 - index.js
 - A.js
 - B.js

index.js

module.exports = function(includeFile){
    return require('./'+includeFile);
};

A.js

module.exports = mongoose.model('A', ASchema);

B.js

module.exports = mongoose.model('B', BSchema);

in your app.js

APP.models = require('./models');  // a global object

And when you need it

// Use A
var A = APP.models('A');
// A.find(.....

// Use B
var B = APP.models('B');
// B.find(.....
adam8810
  • 721
  • 1
  • 7
  • 22
hotienvu
  • 675
  • 5
  • 9
10

I try to avoid globals as much as possible, since everything is by reference, and things can get messy. My solution

model.js

  try {
    if (mongoose.model('collectionName')) return mongoose.model('collectionName');
  } catch(e) {
    if (e.name === 'MissingSchemaError') {
       var schema = new mongoose.Schema({ name: 'abc });
       return mongoose.model('collectionName', schema);
    }
  }
5

Actually the problem is not that mongoose.model() is instantiated twice. The problem is that the Schema is instantiated more than one time. For example if you do mongoose.model("Model", modelSchema) n times and you are using the same reference to the Schema this would not be a problem for mongoose. The problem comes when you use another reference of schema on the same model i.e

var schema1 = new mongoose.Schema(...);
mongoose.model("Model", schema1);
mongoose.model("Model", schema2);

This is the situation when this error occurs.

If you look at the source (mongoose/lib/index.js:360) this is the check

if (schema && schema.instanceOfSchema && schema !== this.models[name].schema){
    throw new mongoose.Error.OverwriteModelError(name);
}
  • 1
    great answer, thanks! and as such, one can bypass the call to schema with a check on whether mongoose.models[name] contains the item already – Jay Edwards Sep 14 '17 at 23:15
3

I found it better to avoid global and exception handing-

var mongoose = require("mongoose");
var _ = require("underscore");

var model;
if (_.indexOf(mongoose.modelNames(), "Find")) {
    var CategorySchema = new mongoose.Schema({
        name: String,
        subCategory: [
            {
                categoryCode: String,
                subCategoryName: String,
                code: String
            }
        ]
    }, {
        collection: 'category'
    });
    model = mongoose.model('Category', CategorySchema);
}
else {
    model = mongoose.model('Category');
}


module.exports = model;
Kavi
  • 176
  • 1
  • 12
1

This is because require one Model in two paths.

// Comment Model file

var mongoose = require('mongoose')
var Schema = mongoose.Schema

var CommentSchema = Schema({
  text: String,
  author: String
})

module.exports = mongoose.model('Comment', CommentSchema)

// Seed file

const commentData = {
  user: "David Lee",
  text: "This is one comment"
}
var Comment = require('./models/Comment')

module.exports = function seedDB () {
  Comment.create(commentData, function (err, comment) {
    console.log(err, commemt)
  })
}

// index file

var Comment = require('./models/comment')
var seedDB = require('./seeds')
seedDB()
const comment = {
  text: 'This girl is pretty!',
  author: 'David'
}
Comment.create(, function (err, comment) {
    console.log(err, comment)
 })

Now you will get throw new mongoose.Error.OverwriteModelError(name), Cuz you require Comment model in two different ways. Seed file var Comment = require('./models/Comment'),Index file var Comment = require('./models/comment')

DavidLee
  • 53
  • 1
  • 9
0

mine got solved with this code:

  module.exports = mongoose.models.nameOne || mongoose.model('nameOne', PostSchema);
fruitloaf
  • 1,628
  • 15
  • 10
0

The problem itself is to create models with the same name, when we pass "user" as first argument we are defining only the name of the model, NOT that of the collection

ex: mongoose.model("cadastry", cadastryUserSchema, "users")

ex: mongoose.model(nameModel, SchemaExample, NameQueyCollection)

TypeScript info name: string, schema?: mongoose.Schema<...> | undefined, collection?: string | undefined

Davi Artur
  • 11
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 16 '22 at 06:04