Q: How and when should I add timestamps to my MongoDB documents? And can I do it with Studio 3T?
Welcome to the latest Studio 3T Ask Manatees Anything – #Studio3T_AMA. Want to know how to use Studio 3T to make your MongoDB life better? Just tweet and use #Studio3T_AMA or email [email protected].
A: If you have documents that change over time, then timestamps are great for keeping track of changes in those documents.
In a previous AMA we showed how you can get by using the timestamp embedded into a document’s server-generated _id
when the document is created. That gives you a creation date, but it doesn’t address updating at all. Worse still, that creation date is both sticky and fragile. Sticky because if you move the document to another server, the _id timestamp will still point to the original creation date. Fragile because if you regenerate the _id
, all the creation date information is replaced with the current time.
So while it is handy to know there is a timestamp in server generated _id
fields, you should never build your application architecture around using them. Instead, you should look to adding two (or more) explicit fields for timestamps.
Writing timestamps
Making sure that all your applications create and update MongoDB timestamps is going to be the hardest part of this process; MongoDB has no automatic timestamp support, so every one of your applications is going to have to make sure they do one of two things when working with the database: write a createdAt
field, or update an updatedAt
field.
An exception might be if you use a package like Mongoose to work with MongoDB. It has support for adding automatic timestamps to your application’s schema. If your application framework hasn’t got that, it is down to developer rigor to make sure timestamp fields are managed correctly.
In practice, that means when inserting a document for the first time, you set the “createdAt” field in your schema to the current date, e.g new Date(). You’ll typically want to set the updatedAt
field to the same value. When modifying a document, you’ll just need to set the updatedAt
field with the current Date.
Writing timestamps in Studio 3T
Let’s step through this practically with a very simple schema, a name field and timestamp fields createdAt
and updatedAt
. Let’s insert a document into that collection:
We’re using ISODate()
to generate a timestamp here, date and time at GMT+0. Don’t ever think about timestamps in any other timezone. You just need a dependable, regular and consistent timestamp and UTC aka GMT+0 is your only option. If we add this document and then pull it up in the viewer, we’ll see:
ISODate()
with no parameters is the current date, ISODate
with a string parameter gets that string parsed into a date value. Notice how the two date strings end with “+0000”. That means these are UTC dates.
Now, if we want to edit this record, we have to remember to preserve the createdAt
and update the updatedAt
. Like this:
We’re changing our name field to "Document Three Three Three"
, but more importantly we are updating the updatedAt
field with ISODate()
and not changing the createdAt
field. If we check the results:
With An Update
Most of the time, we update documents rather than completely replace them. So let’s look at how to refresh MongoDB timestamps in an update. We’ll select the "Document Three Three Three"
value in our Table View and bring up the Update Dialog by clicking on the icon:
Ok, this update will only affect this particular document. Learn more about Update in Smart and Safe MongoDB Multi-Documents Updates. Clicking on the Update tab will show the change we would make:
This is actually no change at all. Update has simply created a template based on the currently selected field. If we just changed the value of the name
, updatedAt
would not be changed, so we should need to update that too:
Again, we update it with ISODate()
to write in the current date. Click Update and then view the document:
And there we can see the updatedAt
is, indeed, updated.
Node.js/JavaScript timestamps
As a final example, here’s some Node.js/JavaScript code which does a similar update to the one above:
var result = await collection.updateMany(
{ _id: ObjectId("6169898bc8646c0c1127e257") },
{ $set: { name: "Three Again", updatedAt: new Date() } }
);
Which just updates the updatedAt
field. When you are creating new documents, you can use the same procedure:
var result = await collection.insertOne({
name: "Four",
createdAt: new Date(),
updatedAt: new Date(),
});
The Truth about MongoDB Timestamps
Now here’s something you need to know. We’ve been talking about timestamps in this article, these timestamps have nothing to do with the Timestamp
type in MongoDB. Our timestamps are simply Date
types and nothing more. Always keep your timestamp information in Date objects. The MongoDB Timestamp
type is actually an internal MongoDB BSON type that you should not use. Using Date types in your collections is best practice. They are easily read and set and portable.
Now, all you need to do is add timestamps to your applications and remember when updating to update the updatedAt
field, or whatever you decide to call it.