Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB / Mongoose timestamps not updating

Schema:

var schema = new Schema({...}, {
    timestamps: true,
    id: false,
    toJSON: {
        virtuals: true,
    },
    toObject: {
        virtual: true,
    }
});
schema.virtual('updated').get(function () {
    if(typeof this.updatedAt === "undefined" && typeof this.createdAt === "undefined") return "";
    var updated = (typeof this.updatedAt === "undefined") ? this.createdAt : this.updatedAt;
    return "Updated "+moment(updated).fromNow();
});

This code was working recently - updatedAt for a particular instance comes up as August 24th, however any new edits to the document doesn't update the timestamp.

Feels like I'm missing something very silly here.

like image 876
Simon Poole Avatar asked Sep 14 '16 16:09

Simon Poole


People also ask

What is timestamps true in Mongoose?

If you set timestamps: true , Mongoose will add two properties of type Date to your schema: createdAt : a date representing when this document was created. updatedAt : a date representing when this document was last updated.

How does a Mongoose save time?

You can set the timestamps property to true when defining a Schema and mongoose will add a createdAt and updatedAt field for you. Mongoose will also update the updatedAt field for you when you do any update operation.

What is timestamp in MongoDB?

Working of the timestamp in mongodb is simple, where when executed, the timestamp method will call the currentDate(), which will pick the current date and time of the system. This picked date and time will be stored in the collection, along with the other data values.


3 Answers

Can try by modify your schema like:

var schema =new Schema({..}, 
           { timestamps: { createdAt: 'createdDate',updatedAt: 'updatedDate' } 
});

for this schema timestmps will update on save(), update() and findOneAndUpdate(). so no need schema.virtual('updated')...

Process-2

added createdDate and updatedDate with Date type in your schema and update these date fields using schema plugin.

like:

var mongoose = require('mongoose'),
    Schema   = mongoose.Schema,
    SchemaPlugin = require('../helpers/schemaPlugin');
  var schema =new Schema({..},
    createdDate: {
      type: Date,
      default: Date.now
    },
    updatedDate: {
      type: Date,
      default: Date.now
    }
  });

  schema.plugin(SchemaPlugin);

in schemaPlugin.js file:

module.exports = function(schema) {

  var updateTimestemps = function(next){
    var self = this;


    if(!self.createdAt) {
      self.createdDate = new Date();
      //or self.update({},{ $set: { createdDate : new Date(), updatedDate: new Date() } });
    } else {
      self.updatedDate= new Date();
      //or self.update({},{ $set: {updatedDate: new Date() } });
    }
    next();
  };

  schema.
    pre('save', updateTimestemps ).
    pre('update', updateTimestemps ).
    pre('findOneAndUpdate', updateTimestemps);
};
like image 193
Shaishab Roy Avatar answered Sep 22 '22 08:09

Shaishab Roy


Stumbled upon the same thing, figured out that if the property updatedAt is set on my object when I'm updating it with findOneAndUpdate() (or update()), it won't update it.

In my case, solved it by making sure updatedAt isn't set before update:

delete thing.updatedAt;

Thing.findOneAndUpdate(
  { _id : thing._id },
  thing,
  function (err, result) {
   …

Credit to Valeri Karpov for his answer on Github.

like image 28
Bigood Avatar answered Sep 24 '22 08:09

Bigood


updatedAt and createdAt both created on same time when a new document is entered into the database using mongoose so your checking of whether updatedAt is undefined or not is illogical as both will have the same value when new document is created.

Whenever you use a mongoose update function or findByIdAndUpdate or findOneAndUpdate the value of the updatedAt will be updated automatically.Use Mongodb client like mongochef or robomongo to directly check the value of the updatedAt.

like image 31
kshitij agrawal Avatar answered Sep 23 '22 08:09

kshitij agrawal