Mongoose: how to get warnings on undocumented fields? - node.js

If I have the following Schema for my colletion
new Schema({ name: String })
I then mistakenly try to create a model for this schema
new Model({name: 'Manu', address: '5 Rosier Road'}).save()
The address field is not stated in the schema and so is not added to the document and only {name: 'Manu'} is saved.
This is the normal behavior but I would like to have mongoose warn me that my code sends too much data.
Is there any way to configure mongoose to warn on such things ? Any plugin I can find to do so ?
I think it would be a very valuable info to have to detect bugs and mongoose knows how to detect them already

Since additional data are not saved into MongoDB, why it should provide warnings?
To my understanding, MongoDB works on Key-Value pairs. So, key-value can be in any order, but, it will saved as per schema definition.
I also think it is developer's responsibility to check the data before inserting into the database. I personally validate the fields before inserting into the database via code.

Related

How to add timestamps to existing records in MongoDB

I am having a collection 'users' in MongoDB which contains multiple records without timestamps. I am using that collection with my node application and have set timestamps to true as shown:
const userSchema = new Schema({
...
},{
timestamps: true
});
I wanted to apply timestamps to the existing records and use it with my node application in future. If I make new fields 'createdAt' and 'updatedAt', will they work with my Mongoose schema? Or if there is any alternative way to achieve the task, please enlighten me as I am new to node and mongo in general.
first of all, I think this applies cannot affect the existing collections in the database, cause these fields are just a bunch of documents you inserting with existing/updating operations.
in MongoDB, everything is just a document and MongoDB does not care about data you store inside a collection, no validation here.so mongoose comes in for handling those validations and etc. if you change a schema in a collection it only effects to incoming requests from now on. but be careful if conflict fields happen, you will get an error for getting collections.
in short answer: MongoDB does not know when data stored or edited
but you can get timeStamp of creation in mongo ObjectId:
https://docs.mongodb.com/manual/reference/method/ObjectId.getTimestamp/index.html

mongoose update fields and add new field

I already googled a lot but unfortunately, I'm unable to solve my problem...
I've some documents in my MongoDB and now I added a new optional field to my mongoose schema. Unfortunately, I cannot update my existing documents with this new field.
MyModel.findByIdAndUpdate(req.body.modelId, {$set: req.body}, {new: true})
This only updates the existing fields but unfortunately it doesn't add the new field.
How can I force mongoose to add the new field to the document?
Update: My mistake. My schemas are having their own repository because I'm sharing them between different projects. I forgot to update them in the respective project. Now everything works perfect.
You should update the document like this:
Model.update({_id :req.body.modelId },{$set : {new_field: "value"}})
Mongoose is probably doing something between, so it is better to bypass it.

MongoDB, Mongoose - what is the best way for adding non-persistent data field to the schema?

I have Mongoose schema and I need to add a non-persistent field to it. The point of this field is to store some status, related to persistent data fields, but without need to store it to the database. I see that some Mongoose alternatives provide such a feature e.g. https://github.com/simpleviewinc/mongolayer#modeladdfieldargs, however I am not able to find similar one inside Mongoose.
Any tip would be greatly appreciated!
In mongoose you have the concept of virtual fields. See doc (http://mongoosejs.com/docs/guide.html#virtuals).
See also related topic at Adding 'virtual' variables to a mongoose schema?

Mongoose - create model from existing db data

Using Mongoose, I have a document that was previously pulled from the database, complete with an _id property, in raw Object format (IE, without all of the document methods, just straight from the db).
How can I use that data to create an instance of mongoose.Model without the system assigning the model a new _id? I want to then eventually save that model and have it update the existing document in the database.
Update: using a combination of #Jack Newcombe's method, and subsequently setting model.isNew to false, I get the following error: "Mod on _id not allowed". So now it knows to update, but Mongoose is not removing the _id field from the update request. There has to be one more system property on the Model that tells Mongoose whether or not to remove the _id during an update request. Any ideas?
I've figured it out, but I'm sure there is a better way. I'm surprised there isn't a way to do this easily with Mongoose's API.
Anyway, you need to the following:
Create the model like this: var model = new Model(data,
{_id:false});
Manually set model.isNew to false
Manually tell Mongoose that the _id field hasn't been modified, like this: delete model.$__.activePaths.states.modify._id
The reason I'm not so fond of this is because I'm taking advantage of the fact that JavaScript doesn't have true protected methods, and I'm basically hacking Mongoose in order to get it to work. So I'd love to hear other answers if anyone has.
You can prevent the schema for the model from automatically generating an _id by passing in an option that sets the _id to false:
var schema = new Schema({ name: String }, { _id: false });
Source: http://mongoosejs.com/docs/guide.html#_id

How does `mongoose` handle adding documents that have FIELDS that are __NOT__ part of the schema?

I'm playing around with quick start guide for mongoose.
http://mongoosejs.com/docs/index.html
I assumed that it would throw an error when I saved a document with a field NOT defined in the schema. Instead, it created a new document in the collection but without the field. (Note: I realize mongodb itself is "schema-less" so each document in a collection can be completely different from each other.)
two questions
How does mongoose handle adding documents that have fields that are NOT part of the schema? It seems like it just ignore them, and if none of the fields map, will create an empty document just with an ObjectId.
And how do you get mongoose to warn you if a specific field of a document hasn't been added even though the document successfully saved?
(The question is - I believe - simple enough, so I didn't add code, but I definitely will if someone requests.)
Thanks.
Q: How does mongoose handle adding documents that have fields that are NOT part of the schema?
The strict option, (enabled by default), ensures that values passed to our model constructor that were not specified in our schema do not get saved to the db.
- mongoose docs
Q: How do you get mongoose to warn you if a specific field of a document hasn't been added even though the document successfully saved?
The strict option may also be set to "throw" which will cause errors
to be produced instead of dropping the bad data. - mongoose docs
...but if you absolutely require saving keys that aren't in the schema, then you have to handle this yourself. Two approaches I can think of are:
1. To save keys that aren't in the schema, you could set strict to false on a specific model instance or on a specific update. Then, you'd need to write some validation that (a) the values in the document conformed to your standards and (b) the document saved in the database matched the document you sent over.
2. You could see if the Mixed schema type could serve your needs instead of disabling the validations that come with strict. (Scroll down to 'usage notes' on that link, as the link to the 'Mixed' documentation seems broken for the moment.)
Mongoose lets you add "validator" and "pre" middleware that perform useful functions. For instance, you could specify the required attribute in your schema to indicate that a specific property must be set. You could also specify a validator that you can craft to throw an error if the associated property doesn't meet your specifications. You can also set up a Mongoose "pre" validator that examines the document and throws an Error if it finds fields that are outside of your schema. By having your middleware call next() (or not), you can control whether you proceed to the document save (or not).
This question/response on stackoverflow can help with figuring out whether or not an object has a property.

Resources