I blogged about using incremental ids with mongodb previously, so have a read of that for more information.

Although it’s not ideal, we can use sequential / incremental IDs with MongoDB.
Sometimes (when migrating legacy systems for example) we just can’t get away from using ints for id’s.

While working on implementing MongoDB with N2CMS recently, I came across this very problem.

All IDs are integers, and this can’t be changed
(technically, it could… but I don’t think it’s appropriate… yet)

So, we needed to find a way of generating incremental IDs

Fortunately, the MongoDB driver for .net allows us to write and use our own IdGenerators

So, with that in mind, I’ve created this:

www.github.com/alexjamesbrown/MongDBIntIdGenerator

It works on the principal outlined in my previous blog post:
Have a collection that keeps track of collection names, and increment their sequence each time one is inserted

This works well, on single server setups.

I have not yet tested on other setups, but intend to soon.

While playing with incremental IDs with Mongo DB the other day, I stumbled across a bug in mongodb.

Consider the following command:

db.sequence.findAndModify({ 
     query: {"_id": "customer"}, 
     update : {$inc : {"seq":1}}, 
     fields:{"_id":0}, 
     upsert:true, 
     new:true})

Notice the fields:{"_id":0}, part (highlighted)

According to the documentation, this should prevent the id from being returned, however when I try and execute this command, I get this error:

Uncaught exception: findAndModifyFailed failed: "exception: assertion c:\\builds\laves\\mongo\\windows_64bit_v1.6\\mongo\\db\\../bson/bsonbjbuilder.h:115"

image

I opened a ticket with their issue tracking system (Jira)

After a day or so, I had a response that this was caused by a limitation to how FindAndModify was implemented.

Luckily, they’re planning on re-implementing this feature (see this ticket) which should remove this restriction.

In the meantime, the method of auto-incrementing ID’s described in my previous post will still work, but it will return the _id as well.

In a future release of mongodb, we’ll be able to strip this out, and make it even speedier!

MongoDB – Incremental IDs

I’ve been reading a lot recently on MongoDB and the use of incrementing an ID

This article offers an in depth look: http://shiflett.org/blog/2010/jul/auto-increment-with-mongodb

Taking this a little further, and from reading the findAndModify documentation I put together the following:

  db.sequence.findAndModify({
    query: {"_id": "customer"},
     update : {$inc : {"seq":1}},
     upsert:true,
     new:true})

Here is what this command does:

  • Finds (or creates) the “sequence” collection
  • Gets the document with id “customer”
  • Increments the value of “seq” by 1
  • If this document doesn’t exist, it creates it (upsert:true)
  • Returns the new value of “seq”

Of course, in production, I’d shorten “seq” to just “s” or something like that, for even speedier responses!

The advantages of this are you don’t need to initialise your “sequence” collection first, or check if your document exists first. If it doesn’t exist, it will create it!

Important Note

At the time of writing, unfortunately, the whole document (ie- id and seq) is returned with this operation

According to the documentation, we should be able to specify “fields” to remove the id from the returned doc, however this doesn’t seem to work.

I have opened a ticket on MognoDB Jira for this.

See this post for more information.