Mongoose - create model from existing db data - node.js

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

Related

When manually using new model(), Is it possible to modify a document before save()ing it, using mongoose update operators?

With mongoose, they very often give documentation in which they create a new document on a model on the spot, and then modify a field and save it, like so:
const Tank = mongoose.model('Tank', yourSchema);
const small = new Tank({ size: 'small' });
small.size = 'big'
small.save()
// saves doc as {size:'big'}
What i want to know is if its possible to use this way of creating a doc and modifying it using mongoose doc methods and operators, for example:
small.update({size:'reallyBig'})
small.save()
//i would expect the document to now be saved with size:'reallyBig', but it doesn't seem to work this way
This example seems useless, but i want to see if this basic principle is possible because i want to use some mongoose operators for more complex calculations and updates of the document, before it is even saved to the databse.
The problem im having is that this doesnt automatically create an ObjectID for the doc, and Document.updateOne() seems to internally use the doc's _Id to find it... but i havent even saved it so im not sure how it's supposed to find it.
I want to be able to use ops like $inc, $count, $addToSet and such, but am i missing something to be able to use these methods to modify the doc before save()?

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: how to get warnings on undocumented fields?

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.

mongoose schema model _id

I'm using mongoose 5.0.9. My question is about the _id of document.
I'd like to get `_id generated from mongodb when new document inserted. In this way, I could not define the _id in my mongoose schema/model. If I do, the mongoose will fail since I don't provide the value for _id.
However, I want to use the _id in my page. If I don't define it in my schema/model, I could not get it when querying.
One solution I thought is to define two schemas: one for inserting document without _id, and the other is for querying, updating, etc, with _id.
I don't want to make things to complex, so I don't think this is good idea.
what is the best practice for this _id?
Thanks in advance.
Richard

Mongoose create custom _id from other fields

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

Resources