Timestamp and ObjectId in mongoDB

Every record in mongoDB has field _id, that must be unique inside collection. By default type of this field is ObjectId, and it is assigned automatically if field is not set.

Lets look at ObjectId more carefully.

It is 12 bytes that includes:

  • a 4-byte value representing the seconds since the Unix epoch,
  • a 3-byte machine identifier,
  • a 2-byte process id, and
  • a 3-byte counter, starting with a random value.

As we see, first 4 bytes represent creation date and we can use it:

  • sort by field _id and you’ll get documents in creation time order
  • we can get creation time of the document from ObjectId

But keep in mind, that this date has accuracy of seconds. If two documents are created during one second then their order is not defined in sorting by _id.

So, if accuracy of second is enough for us then we do NOT need field like this:

{
    created_at: ISODate("2015-01-18T12:07:47.036Z")
    // other fields
}

as creation date is included in _id.

Get date from ObjectId

In mongoDB shell date can be retrieved by method getTimestamp():

> db.users.findOne()._id.getTimestamp()
ISODate("2015-01-18T09:07:47Z")

And in python code - by attribute generation_time

>>> from pymongo import MongoClient
>>> db = MongoClient().db_name
>>> user = db.users.find_one()
>>> user['_id'].generation_time
datetime.datetime(2015, 1, 18, 9, 7, 47, tzinfo=<bson.tz_util.FixedOffset object at 0x10e758d50>)

Date is returned in UTC and in python it is aware datetime with timezone.

To be clear, these versions i use:

  • mongoDB v2.6.6
  • pymongo v2.7.2

P.S. thanks @eugeneglybin to pointing out.