16

I have 3 kind of records,

1)Categories,
2)Topics  and
3)Articles 

In my mongodb, i have only 1 colection named 'categories' in which i stroe the above 3 types of documents.

For these 3 modules,i wrote 3 models(one each) in such a way like below,

mongoose.model('categories', CategorySchema);
mongoose.model('categories', TopicSchema)
mongoose.model('categories', ArticlesSchema)

like....mongoose.model('collection_name', Schema_name)

but when i run my code ,it throws error that

Cannot overwrite `categories` model once compiled.

If i change the above models like this,

mongoose.model('category','categories', CategorySchema);
mongoose.model('topics','categories', TopicSchema)
mongoose.model('articles','categories', ArticlesSchema)

It is creating 2 collections named topics and articles which i dont want. This is my issue right now,can anyone suggest me help.....Thanks....

MMR
  • 2,869
  • 13
  • 56
  • 110
  • you have to define 3 models for 3 schema – chirag Oct 17 '16 at 05:55
  • Said differently, a model maps directly to _one_ document of _a_ collection. What you're trying to do here isn't possible -- since really you have _one_ model/collection in your DB that contains documents which themselves contain a type property you are using to differentiate on. – prasanthv Oct 31 '18 at 18:26

5 Answers5

51

Try-

mongoose.model('category', CategorySchema, 'categories');
mongoose.model('topics', TopicSchema, 'categories');
mongoose.model('articles', ArticlesSchema, 'categories');

As mentioned in docs: http://mongoosejs.com/docs/api.html#index_Mongoose-model

Mongoose#model(name, [schema], [collection], [skipInit])

Defines a model or retrieves it.

Parameters:

  • 1st param - name <String> model name
  • 2nd param - [schema] <Schema> schema name
  • 3rd param - [collection] <String> collection name (optional, induced from model name)
  • 4th param - [skipInit] <Boolean> whether to skip initialization (defaults to false)

See - https://stackoverflow.com/a/14454102/3896066

Community
  • 1
  • 1
saurav
  • 972
  • 11
  • 24
  • 3
    "The first argument is the singular name of the collection your model is for. Mongoose automatically looks for the plural version of your model name" - directly from the Model docs -- https://mongoosejs.com/docs/models.html – prasanthv Oct 31 '18 at 18:23
7

As you stated, When you write this,

mongoose.model('categories', CategorySchema);
mongoose.model('categories', TopicSchema);
mongoose.model('categories', ArticlesSchema);

The output becomes inappropriate so do this instead,

mongoose.model('category', CategorySchema);
mongoose.model('topic', TopicSchema);
mongoose.model('article', ArticlesSchema);

Bonus tip. Mongoose makes your collection name plural by default so change a little code if you want your collection name as you wrote.

mongoose.model('category', CategorySchema,'category');
mongoose.model('topic', TopicSchema,'topic');
mongoose.model('article', ArticlesSchema,'article');
Christopher Nolan
  • 930
  • 1
  • 11
  • 15
4

"The first argument is the singular name of the collection your model is for. Mongoose automatically looks for the plural version of your model name" - directly from the Model docs -- https://mongoosejs.com/docs/models.html

prasanthv
  • 2,442
  • 2
  • 21
  • 17
0

You can use Mongoose Discriminators (http://mongoosejs.com/docs/discriminators.html) for that.

This article has a good and easy example of how to do that: https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb-mongoose#using-mongoose-discriminators-to-store-data-in-a-single-collection.

0

mongoose.model() method takes arguments in the following order,

name: string,
schema: Schema, 
collection?: string, 
skipInit?: Boolean

Example:

mongoose.model('todoModel','todoSchema', 'todoCollection');
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
prashanthh
  • 21
  • 4