stackers
stackers

Reputation: 3279

How to update MongoDB createdAt date

I am trying to update the automatically added createdAt date on a record to right now.

Here the code I am using:

Document.findOneAndUpdate({_id: docId}, {createdAt: new Date()}, function(err, updated) {});

It works on my dev environment, but not the server. It does not return an error, but does not update the record, just returns the unchanged record.

I tried formatting it with new Date().toISOnew Date().toISOString() or .toGMTString() but both still only work on the dev environment. Both have node 6.10, but the server has mongo 3.4.4 and the dev has mongo 3.2.10.

If I add another field to be updated (second arugment), that field gets updated fine, but createdAt remains unchanged.

Upvotes: 4

Views: 8907

Answers (4)

Mukund Khunt
Mukund Khunt

Reputation: 11

Here, several reasons are possible for not updating the MongoDB collection field createdAt:

  1. Your MongoDB collection schema definition has not used the timestamps: true option.
  2. You need to define the createdAt field in your schema definition.
const testSchema = new mongoose.Schema({
  // ...other fields,
  createdAt: {
    type: Date,
    default: Date.now
  },
});

const testModel = mongoose.model('test', testSchema);

const result = await testModel.findOne({
  _id: ObjectId(id)
});

result.createdAt = new Date();
// Save the latest date value into the "createdAt" field.
await result.save();

Upvotes: 1

Aditya Subramanian
Aditya Subramanian

Reputation: 11

If you really want to update the createdAt field then you can start by finding the document first and then updating the field like this:

const result = await schema.findOne({ _id: id });
if (result) {           
    result.createdAt = new Date(createdAt);
    await result.save();
}

Upvotes: 1

Ana
Ana

Reputation: 1

I do not know if it works for update, but for create, I first make sure have the createdAt field abled in my DB and then set the createdAt field like this: {createdAt: moment().toISOString()}

because createdAt and updatedAt are ISO strings.

Edit: Just like Nigel mentioned, I do use moment library but new Date().toISOString() gives you the same result.

Upvotes: 0

vorillaz
vorillaz

Reputation: 6286

Automatic createdAt and updatedAt fields are populated by mongoose using the timestamps option as

const schema = new Schema({
  // Your schema...
}, {
  timestamps: { createdAt: true, updatedAt: false }
})

If you take a look at the source code you'll see that createdAt is excluded from updates. It's fairly easy though to modify your schema accordingly.

const schema = mongoose.Schema({
  name: String,
  createdAt: { type: Date, default: Date.now }
});

const Test = mongoose.model('test', schema);

const john = await Test.create({name: 'John Doe'});
console.log(john);

const updatedJohn = await Test.findOneAndUpdate({name: 'John Doe'}, { createdAt: Date.now() });
console.log(updatedJohn);

Upvotes: 5

Related Questions