Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use the timestamp in "_id"?

I need monitor the time of the records been created, for further query and modify.

first thing flashed in my mind is give the document a "createDateTime" field, with the default value of "new Date()", but Mongodb said the document _id has a timestamp embedded with, and the id was generated when the document was created, so it sounds dummy to add a new field for that.

for too many times, I've seen people set a "createDateTime" for their data, and I don't know if they know about the details of mongodb's _id.

I want know should I use the _id as a "createDateTime" field? what is the best practice? and the pros and cons.

thanks for any tips.

like image 313
Hetfield Joe Avatar asked Feb 16 '14 13:02

Hetfield Joe


2 Answers

I'd actually say it depends on how you want to use the date.

For example, it's not actionable using the aggregation framework Date operators.

This will fail for example:

db.test.aggregate( { $group : { _id:  { $year: "$_id" } } })

The following error occurs:

"errmsg" : "exception: can't convert from BSON type OID to Date"

(The date cannot be extracted from the ObjectId.)

So, operations that are normally simple date operations become much more complex if you wanted to do any sort of date math in an aggregation. It would be far easier to have a createDateTime stamp. Counting the number of documents created in a particular year and month would be simple using aggregation with a distinct createdDateTime field.

You can sort on an ObjectId, to some degree. The remaining 8 bytes of the ObjectId aren't sortable in a meaningful way. Most MongoDB drivers default to creating the ObjectId within the driver and not on the database. So, if you've got multiple clients (like web servers for example) creating new documents (and new ObjectIds), the time stamps will only be as accurate as the various servers.

Also, depending the precision you'd need, an ISODate value is stored using 8 bytes, rather than the 4 used in an ObjectId.

like image 184
WiredPrairie Avatar answered Oct 21 '22 08:10

WiredPrairie


Yes, you should. There is no reason not to do, besides the human readability while directly looking into the database. See also here and here.

If you want to use the aggregation framework to group by the date within _id, this is not possible yet as WiredPrairie correctly sais. There is an open jira ticket for that, you might watch. But of course you can do this with Map-Reduce and ObjectID.getTimestamp(). An example for that can be found here.

like image 41
heinob Avatar answered Oct 21 '22 09:10

heinob