Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add created_at and updated_at fields to mongoose schemas

People also ask

What is createdAt and updatedAt?

createdAt : a date representing when this document was created. updatedAt : a date representing when this document was last updated.

Can I set default value in Mongoose schema?

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.

Can Mongoose schema be changed?

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.

What is the difference between schema and model in Mongoose?

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 a deleted field to true. 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" (the deleted 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: {} });

enter image description here
Also you can change createdAt -> created_at by

timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }