I found this (I think?) undesirable behavior in mongoose 3.8.12, when you create a new mongoose model by default it makes its name plural adding an 's' which is perfectly normal, when the model's name already ends with an 's' then save it as it is (expected behavior). The problem is when you have two different models with the same name but one plural and the other singular, then mongoose allows you two create the two but uses the same collection in mongo to store both.
let's say I have a collection named 'car':
mongoose.model('Car', schema);
and a collection 'cars':
mongoose.model('Cars', schema);
both are saved in mongo as 'cars'
I don't think that is the expected behavior.
http://mongoosejs.com/docs/api.html#index_Mongoose-model
When no collection argument is passed, Mongoose produces a collection name by passing the model name to the utils.toCollectionName method. This method pluralizes the name. If you don't like this behavior, either pass a collection name or set your schemas collection name option.
Since Car turns into Cars, and Cars is already plural you end up with the same collection name. Models are generally given the singular name. The link above lists several methods to set a custom collection name.
Of course, you can always create a new issue on the project's GitHub repo.
Related
In my NodeJS project, I have created a mongoose schema which I changed midway through the project. More specifically, I added the unique parameter to a field.
However, this change does not seem to reflect as I am still able to create multiple documents with the same value for the parameter which I set as unique
How to fix this issue
Mongoose enforces the unique constraint by creating an index in MongoDB with the unique option.
If you already have duplicates in the collection, that index creation will fail.
Note that you may have to call syncIndexes to update the database with the new index.
I was wondering. I have a lot of coding to do with a function to remove a document from the database. Basically removing just the object is not that much work, but removing the _id reference from all the other models step by step in the right order is the big work load (I pushed the object ID into the other objects so I could create relations and populate later).
I was wondering: is there no function standard in mongoose that instantly removes the document as well as all its objectId references in the documents of the other model types (so completely remove the object and all it's ObjectID references in all the other collections in the DB)?
You can achieve what you are looking for using this NPM package called
cascading-relations here
Why does the model name matter in Mongoose? I understand that given a model name, Mongoose can try to guess the collection name. However, for this application it seems better and easier to just explicitly specify the collection name instead of the model name.
What else is the model name used for in Mongoose?
Mongoose is an Object Data Mapping (ODM) library for node similar to Object Relational Mapping (ORM) in Ruby on Rails and some other frameworks. Therefore, it follows more or less the same rules (or guidelines, as you can override them):
ORM:
Class name capital and singular
Table name small and plural
Class object mapped/translated to table row and vice versa
Class and its objects have methods/hooks
ODM:
Model name capital and singular (e.g. User)
Collection name small and plural (e.g. users)
Model object mapped/translated to collection document and vice versa (e.g. object of model: new User({name: "abc"}), document in collection: {"name": "abc"})
Model and its objects have methods/hooks (e.g. pre, post hooks; validations etc)
The mapping is between incompatible types, like an object of Ruby class to a row of SQL table; and a JavaScript object of Mongoose model (can have functions, for instance) to a JSON document of mongodb (valid JSON can't have functions).
Since class and table, model and collection are different entities (though related) and serve different purpose, they are named differently (though similarly). Hence the need of model name in Mongoose!
using this line :
var collection = mongoose.connection.db.collection("users");
I get users s collection, now i need to get the schema from that collection ?
Is there a way to do this? thank you.
PS: I dont have any models
if you do not have any models, I'm afraid this can't be done.
the schema is the structural representation of the document, not the collection. You can use the schema (via the model) to enforce that any document added to the collection match some structure, but there's nothing that prevents you from inserting into this collection a different document without this model, that will not match the criteria
so the schema does not live in the DB, it is a part of the mongoose module, and lives in the code. and the way to access it is through the model only
I know that Mongoose populates the _id field automatically with an ObjectID if none is given and that you can overwrite the _id when constructing and instance of the model.
What I want: create the _id from other fields in a transparent way. I want to omit the _id field when creating an instance of the model and then have a function called which fills it. This function should be declared on a Schema level and whoever uses the model does not know that _id was filled by the function instead of Mongoose.
Is there a hook or a parameter of the Schema constructor I missed?
Mongoose 3.0.x
Let's make this more concrete. Imagine a BlogPost and I want to create nice URLs by slugging the title. In order to map the slug to a Mongo Object I hash the slug and turn it into a ObjectID to leverage it's benefits. Now what I'm looking for is a transparent method which allows me to create an instance of BlogPost by only passing in title and have the slug and _id property automatically generated.
use a setter on title which slugifies and idifies for you: https://gist.github.com/3658511
If you want to make sure your code is only executed once the object is created, check for this.isNew inside the setter.
Is this what you are looking for?
You could define a function to create the _id before the model is saved, as in:
http://mongoosejs.com/docs/middleware.html
If this middleware is called after Mongoose creates the _id by default (my guess is it's not), you could tell Mongoose to not create an _id, with the _id option.
http://mongoosejs.com/docs/guide.html#options