How to add timestamps to existing records in MongoDB - node.js

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

Related

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: exclude _id field in inserts

I have a high-concurrency and parallelism situation and would like _id fields to be created by MongoDB and not by mongoose, so that I can use the ObjectId timestamps in the _id field to reliably query documents in the order they were inserted.
Is this possible? Right now I don't see how to do this with mongoose, as marking a schema with {_id: false} and trying to save it returns an error document must have an _id before saving.
Mongoose docs say the _id option only works on subdocuments, hence the error you get (http://mongoosejs.com/docs/guide.html#_id).
It might fit your situation to add a document without mongoose and in a subsequent operation update it through using mongoose (thereby keeping mongoose's Schema functionality etc).

Sub documents vs Mongoose population

I have the following senario:
A user can login to a website. A user can add/delete the poll(a question with two options). Any user can give there opinion on the poll by selecting anyone of the options.
Considering the above scenario I have three models - Users Polls Options . They are as follows, in order of dependency:
Option Schema
var optionSchema = new Schema({
optionName : {
type : String,
required : true,
},
optionCount : {
type : Number,
default : 0
}
});
Poll Schema
var pollSchema = new Schema({
question : {
type : String,
required : true
},
options : [optionSchema]
});
User Schema: parent schema
var usersSchema = new Schema({
username : {
type : String,
required : true
},
email : {
type : String,
required : true,
unique : true
},
password : String,
polls : [pollSchema]
});
How do I implement the above relation between those documents. What exaclty is mongoose population? How is it different from subdocuments ? Should I go for subdocuments or should I use Mongoose population.
As MongoDb hasn't got joins as relational databases, so population is a something like hidden join. It just means that when you have that User model and you will populate Poll Model, mongoose will do something like this:
fetch User
fetch related Polls, by ObjectIds which are stored in User document
put fetched Polls documents into User document
And when you will set User as document and Polls as subdocument, it will just mean that you will put whole data in single document. At one side it means that to fetch User Polls, mongoose doesn't need to run two queries(it need to fetch only User document, because Polls data is already there).
But what is better to choose? It just depends of the case.
If your Polls document will refer in another documents (you need access to Polls from documents User, A, B, C - it could be better to populate it, but not for sure. The advantage of populating is fact, that when you will need to change some Polls fields, you don't need to change that data in every document which is referring to that Polls document(as it will be a subdocument) - in that case in document User, A, B, C - you will only update Polls document. As you see it's nice. I told that it's not sure if populating will be better in that case, because I don't know how you need to retrieve your Polls data. If you store you data in wrong way, you will get performance issues or have some problems in easy data fetch.
Subdocuments are the basic way of storing data. It's great when Polls will be only referring to User. There is performance advantage - mongoose need to do one query instead of two as in population and there is no previously reminded update disadvantage, because you store Polls data only in single place, so there is no need to update other documents.
Basically MongoDb was created to mostly use Subdocuments. As the matter of fact, it's just non-relational database. So in most cases I prefer to use subdocuments. I can't answer which way will be better in your case, because I'm not sure how your DB looks like(in a full way) and how you want to retrieve your data.
There is some useful info in official documentation:
http://mongoosejs.com/docs/subdocs.html
http://mongoosejs.com/docs/populate.html
Take a look on that.
Edit
As I prefer to fetch data easily, take care about performance and know that data redundancy in MongoDb is something common, I will choose to store this data as subdocuments.

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

Batch update with Mongoose

I'm pulling data from a RETS(XML) feed and saving it in a local MongoDB using node and mongoose.
Periodically I need to update the documents and delete the inactive ones as well as add new ones. Rather than making multiple queries to Mongo or the RETS server, I was pulling both and looping through the data.
This works fine but is there a way to save the Mongoose results back to the database with updates and inserts? Or do I need to find each document and update it individually?
On MongoDB, to update multiple documents (not just one) using Mongoose you can use the multi option:
Model.updateMany({
size: 'lage'
}, {
$set: { size: 'large' }
});
See more on in the Mongoose documentation for updating documents and here
For completeness, If any one has multiple query conditions and want to add new fields for every matching documents of query condition then we can go with
var bulk = Person.collection.initializeUnorderedBulkOp();
bulk.find(query1).update(update1);
bulk.find(query2).update(update2);
bulk.execute(callback);
In following documentation, it is said that db.collection.initializeUnorderedBulkOp()
Initializes and returns a new Bulk() operations builder for a
collection. The builder constructs an unordered list of write
operations that MongoDB executes in bulk. MongoDB executes in
parallel the write operations in the list.
https://docs.mongodb.org/v3.0/reference/method/db.collection.initializeUnorderedBulkOp/

Resources