createdAt : a date representing when this document was created. updatedAt : a date representing when this document was last updated.
As mentioned by user whoami, mongoose only sets defaults on insert. If you are using mongoose 4. x and up and MongoDB 2.4. 0 and up you can opt-in to setting default values on update too.
There's nothing built into Mongoose regarding migrating existing documents to comply with a schema change. You need to do that in your own code, as needed.
Mongoose Schema vs. Model. A Mongoose model is a wrapper on the Mongoose schema. A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
UPDATE: (5 years later)
Note: If you decide to use Kappa Architecture (Event Sourcing + CQRS), then you do not need updated date at all. Since your data is an immutable, append-only event log, you only ever need event created date. Similar to the Lambda Architecture, described below. Then your application state is a projection of the event log (derived data). If you receive a subsequent event about existing entity, then you'll use that event's created date as updated date for your entity. This is a commonly used (and commonly misunderstood) practice in miceroservice systems.
UPDATE: (4 years later)
If you use ObjectId
as your _id
field (which is usually the case), then all you need to do is:
let document = {
updatedAt: new Date(),
}
Check my original answer below on how to get the created timestamp from the _id
field.
If you need to use IDs from external system, then check Roman Rhrn Nesterov's answer.
UPDATE: (2.5 years later)
You can now use the #timestamps option with mongoose version >= 4.0.
let ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
If set timestamps, mongoose assigns createdAt
and updatedAt
fields to your schema, the type assigned is Date
.
You can also specify the timestamp fileds' names:
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
Note: If you are working on a big application with critical data you should reconsider updating your documents. I would advise you to work with immutable, append-only data (lambda architecture). What this means is that you only ever allow inserts. Updates and deletes should not be allowed! If you would like to "delete" a record, you could easily insert a new version of the document with some
timestamp
/version
filed and then set adeleted
field totrue
. Similarly if you want to update a document – you create a new one with the appropriate fields updated and the rest of the fields copied over.Then in order to query this document you would get the one with the newest timestamp or the highest version which is not "deleted" (thedeleted
field is undefined or false`).Data immutability ensures that your data is debuggable – you can trace the history of every document. You can also rollback to previous version of a document if something goes wrong. If you go with such an architecture
ObjectId.getTimestamp()
is all you need, and it is not Mongoose dependent.
ORIGINAL ANSWER:
If you are using ObjectId as your identity field you don't need created_at
field. ObjectIds have a method called getTimestamp()
.
ObjectId("507c7f79bcf86cd7994f6c0e").getTimestamp()
This will return the following output:
ISODate("2012-10-15T21:26:17Z")
More info here How do I extract the created date out of a Mongo ObjectID
In order to add updated_at
filed you need to use this:
var ArticleSchema = new Schema({
updated_at: { type: Date }
// rest of the fields go here
});
ArticleSchema.pre('save', function(next) {
this.updated_at = Date.now();
next();
});
As of Mongoose 4.0 you can now set a timestamps option on the Schema to have Mongoose handle this for you:
var thingSchema = new Schema({..}, { timestamps: true });
You can change the name of the fields used like so:
var thingSchema = new Schema({..}, { timestamps: { createdAt: 'created_at' } });
http://mongoosejs.com/docs/guide.html#timestamps
This is what I ended up doing:
var ItemSchema = new Schema({
name : { type: String, required: true, trim: true }
, created_at : { type: Date }
, updated_at : { type: Date }
});
ItemSchema.pre('save', function(next){
now = new Date();
this.updated_at = now;
if ( !this.created_at ) {
this.created_at = now;
}
next();
});
Use the built-in timestamps
option for your Schema.
var ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
This will automatically add createdAt
and updatedAt
fields to your schema.
http://mongoosejs.com/docs/guide.html#timestamps
Add timestamps
to your Schema
like this then createdAt
and updatedAt
will automatic generate for you
var UserSchema = new Schema({
email: String,
views: { type: Number, default: 0 },
status: Boolean
}, { timestamps: {} });
Also you can change createdAt -> created_at
by
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With