Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

uses for mongodb ObjectId creation time

The ObjectId used as the default key in mongodb documents has embedded timestamp (calling objectid.generation_time returns a datetime object). So it is possible to use this generation time instead of keeping a separate creation timestamp? How will you be able to sort by creation time or query for the last N items efficiently using this embedded timestamp?

like image 853
kefeizhou Avatar asked Feb 26 '11 06:02

kefeizhou


People also ask

Should I use MongoDB ObjectId?

You should NOT convert the ObjectId in the database to a string, and then compare it to another string. If you'd do this, MongoDB cannot use the _id index and it'll have to scan all the documents, resulting in poor query performance. Show activity on this post. Don't.

How long is MongoDB ObjectId?

ObjectId values are 12 bytes in length, consisting of: A 4-byte timestamp, representing the ObjectId's creation, measured in seconds since the Unix epoch. A 5-byte random value generated once per process. This random value is unique to the machine and process.

What is the use of ObjectId in MongoDB?

MongoDB uses ObjectIds as the default value of _id field of each document, which is generated while the creation of any document. The complex combination of ObjectId makes all the _id fields unique.

How is MongoDB ObjectId created?

ObjectID is automatically generated by the database drivers, and will be assigned to the _id field of each document. ObjectID can be considered globally unique for all practical purposes. ObjectID encodes the timestamp of its creation time, which may be used for queries or to sort by creation time.


2 Answers

I suppose since MongoDB ObjectId contain a timestamp, you can sort by 'created date' if you will sort by objectId:

items.find.sort( [['_id', -1]] ) // get all items desc by created date.

And if you want last 30 created items you can use following query:

items.find.sort( [['_id', -1]] ).limit(30) // get last 30 createad items 

I am actualy not sure,i just suppose that ordering by _id should work as described above. I'll create some tests later.

Update:

Yes it is so. If you order by _id you will automatically order by _id created date. I've done small test in c#, mb someone interest in it:

  public class Item
  {
    [BsonId]
    public ObjectId Id { get; set; }

    public DateTime CreatedDate { get; set; }

    public int Index { get; set; }
  }



 [TestMethod]
 public void IdSortingTest()
 {
   var server = MongoServer.Create("mongodb://localhost:27020");
   var database = server.GetDatabase("tesdb");

   var collection = database.GetCollection("idSortTest");
   collection.RemoveAll();

   for (int i = 0; i <= 500; i++)
   {
     collection.Insert(new Item() { 
             Id = ObjectId.GenerateNewId(), 
             CreatedDate = DateTime.Now, 
             Index = i });
   }

   var cursor = collection.FindAllAs<Item>();
   cursor.SetSortOrder(SortBy.Descending("_id"));
   var itemsOrderedById = cursor.ToList();

   var cursor2 = collection.FindAllAs<Item>();
   cursor2.SetSortOrder(SortBy.Descending("CreatedDate"));
   var itemsOrderedCreatedDate = cursor.ToList();

   for (int i = 0; i <= 500; i++)
   {
     Assert.AreEqual(itemsOrderedById[i].Index, itemsOrderedCreatedDate[i].Index);
   }
}
like image 99
Andrew Orsich Avatar answered Oct 06 '22 23:10

Andrew Orsich


Yes, you can use the generation_time of BSON ObjectId for the purposes you want. So,

db.collection.find().sort({ _id : -1 }).limit(10)

will return the last 10 created items. However, since the embedded timestamps have a one second precision, multiple items within any second are stored in the order of their creation.

like image 23
user105991 Avatar answered Oct 06 '22 23:10

user105991