172

For example, this code results in a collection called "datas" being created

var Dataset = mongoose.model('data', dataSchema);

And this code results in a collection called "users" being created

var User = mongoose.model('user', dataSchema);

Thanks

Bob Ren
  • 2,139
  • 2
  • 17
  • 16

8 Answers8

274

Mongoose is trying to be smart by making your collection name plural. You can however force it to be whatever you want:

var dataSchema = new Schema({..}, { collection: 'data' })

Community
  • 1
  • 1
aaronheckmann
  • 10,625
  • 2
  • 40
  • 30
  • 62
    I don't understand how adding a "s" makes the framework more intelligent, IMHO, that is a bad idea. Apart from that mongoose is an awesome framework. – Roberto Feb 12 '13 at 08:22
  • 25
    its an old poor choice that breaks backward compatibility if taken out. so we've chosen to stick with it. – aaronheckmann Feb 12 '13 at 16:10
  • WHat do you meant? If I want to use singular collection name instead of pluralized I'll get issues? – Vadorequest Feb 08 '14 at 21:05
  • @Vadorequest - No, it means that if someone updated their mongo instance, their code would break. – Ryan Wheale May 13 '14 at 21:06
  • 1
    it lowercased it and added an s. the first one was acceptable. For those like me who now have data in the wrong collection it's time to rename it – Rivenfall Oct 12 '15 at 16:19
  • 41
    it doesn't just add an 's' but it makes the correct plural of the name. Try for instances with 'mouse', you'll get a collection named 'mice' or with 'person' you'll get 'people'. It was driving me crazy to understand from where these names came from :-) – Enrico Giurin Apr 03 '16 at 01:09
  • this is a really poor design but now i kinda want to know how mongoose does irregular plurals... – swyx Mar 20 '17 at 01:06
  • 3
    This is very crazy now which name do you use to query your collection espically when you have to do it from another interface ? – Xsmael Sep 01 '17 at 16:56
  • 2
    Idiotic IMO. I was wondering why using references to the "history" schema was leading to updates in "histories" without any sort of aliasing going on in the scripts. I eventually came to the conclusion that Mongoose was doing something "clever", hence I found myself here, but it's a non-intuitive default behaviour. – splrs Oct 25 '17 at 10:16
  • 16
    I was freaking out, because I defined "brush" and there was a collection named "brushes". I was trying to find where I'd defined that for almost half an hour and didn't found anything. I thought: "Maybe it's smart and adds that. Probably not, but let's se.... FUUUUUUU" – Fusseldieb Nov 01 '18 at 11:21
  • Yes, very confusing. It's even more of a bad idea when it isn't even consistent. If you have a name ending with a number, it doesn't add an 's', and if you add an s yourself it doesn't add one either. – ram Feb 18 '20 at 21:45
  • what if we wanted to pass 'bus' as the parameter, mongoose will then treat like 'buss' XD XD XD. mongoose if deliberately want to grammar then it should use all the grammar rules, right? – Piyush May 15 '20 at 06:50
  • Just wasted an hour of my life due to this. It's really dumb. Change code essentially without telling the coder. Lame! – JohnAllen Jun 24 '21 at 09:36
  • My collection is ALREADY PLURALIZED: "content" – JohnAllen Jun 24 '21 at 09:37
  • 1
    hate this, i feel like this is hidden convention and opinionated, i spend hours to check why my controller cannot access my database – rickvian Jun 26 '21 at 03:09
63

API structure of mongoose.model is this:

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

What mongoose do is that, When no collection argument is passed, Mongoose produces a collection name by pluralizing the model name. If you don't like this behavior, either pass a collection name or set your schemas collection name option.

Example:

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

or

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

or

var collectionName = 'actor'
var M = mongoose.model('Actor', schema, collectionName);
juliocesar
  • 5,706
  • 8
  • 44
  • 63
Nishank Singla
  • 909
  • 8
  • 15
52

Starting from mongoose 5.x you can disable it completely:

mongoose.pluralize(null);
Andrey Hohutkin
  • 2,703
  • 1
  • 16
  • 17
12

You can simply add a string as a third argument to define the actual name for the collection. Extending your examples, to keep names as data and user respectively:

var Dataset = mongoose.model('data', dataSchema, 'data');

var User = mongoose.model('user', dataSchema, 'user');
Andrea
  • 553
  • 9
  • 12
8
//Mongoose's definition file. NOT your model files
1 const mongoose = require("mongoose");
2 mongoose.pluralize(null);

Adding the linemongoose.pluralize(null) in your Mongoose file will prevent collection name pluralization. You don't need to add this line to your model files.

As seen here.

10110
  • 2,353
  • 1
  • 21
  • 37
2

You can add the collection name as third parameter. See the example using Typescript:

import DataAccess = require('../DataAccess');
import IUser = require("../../Models/Interfaces/IUser");

var mongoose = DataAccess.mongooseInstance;
var mongooseConnection = DataAccess.mongooseConnection;

class UserSchema {
        static get schema () {
        var schema =  mongoose.Schema({
            _id : {
                type: String
            },
            Name: {
                type: String,
                required: true
            },
            Age: {
                type: Number,
                required: true
            }
        });

        return schema;
    }
}
var schema:any = mongooseConnection.model<IUser>("User", 
UserSchema.schema,"User");
export = schema;
sebu
  • 2,824
  • 1
  • 30
  • 45
1

At the end of defining your schema on the next line Use this code

module.exports = mongoose.model("State", "StateSchema", "state")

Assuming that your state is what you want to use on your db to avoid s as states

Click the link to view the picture properly

4b0
  • 21,981
  • 30
  • 95
  • 142
Chukwuemeka Maduekwe
  • 6,687
  • 5
  • 44
  • 67
-2

Mongoose compiles a model for you when you run this command

var schema = new mongoose.Schema({ name: 'string', size: 'string' });
var child = mongoose.model('child', schema);

The first argument is the singular name of the collection your model is for. Mongoose automatically looks for the plural, lowercased version of your model name. Thus, for the example above, the model child is for the children collection in the database.

Note: The .model() function makes a copy of schema. Make sure that you've added everything you want to schema, including hooks, before calling .model()!

Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
Kushagra
  • 3
  • 4