views:

89

answers:

3

The ids in RDBMS's are usually simple integers that go from 0 to whatever number, but typically you can keep them in the 5 digit range so that you can make urls that look like this

myawesomeblog.com/posts/23456

but with mongodb the unique identifiers for each record look like this. 47cc67093475061e3d95369d

and building and app based on that would lead to urls like this myawesomeblog.com/posts/47cc67093475061e3d95369d

I don't like that? Is there anyway to make mongo give you integer based id numbers that are shorter and unique? (like MySQL)

+1  A: 

Here is a link to create an incrementing value from the DOCS

http://www.mongodb.org/display/DOCS/Atomic+Operations#AtomicOperations-%22InsertifNotPresent%22
David Lyod
Yeah I already saw that, it didn't make a lot of sense to me.Where does that function go? In the Mongo Source code? Rewritten for ruby?
concept47
All it effectively doing is pulling every result and its ID field to increment a value. You can store it in mongo itself (like a stored procedure) and just reference it each time.http://en.wikipedia.org/wiki/MongoDB#Server-Side_JavaScript_Executionhttp://neovintage.blogspot.com/2010/07/mongodb-stored-javascript-functions.html
David Lyod
+1  A: 

One way I've tried (and it seems to work) is to create a Sequences collection with documents like:

{ Name : "Posts", Value : 12345, _id : ObjectId("47cc67093475061e3d95369d") }

Prior to inserting into the Posts collection, you'd grab the current Sequence with name "Posts" and increment its value. Then use that value as either a URL friendly ID or an ObjectId for your new Post document.

This approach is sort of like using Oracle's SELECT seq.NEXTVAL FROM DUAL as primary keys.

Not perfect, but it avoids having to grab all documents in a collection and having to find the max value of some ID.

John Zablocki
+1  A: 

Anything that creates an incrementing key will not work once you start using replication. I'm using something generate a unique SHA prefix sort of like git does. It doesn't give you an integer key, but it could easily be modified to. It also isn't guaranteed to be unique, but you have much less chance of a collision than with an incrementing key. I've got the following stuff in my model:

before_create :set_short_id

def set_short_id
  prefix_length = 5
  sha = Digest::SHA1.hexdigest(self.to_json)
  short_id = nil
  while short_id.nil? || Ticket.first(:short_id => short_id)
    short_id = sha.first(prefix_length)
    prefix_length += 1
  end
  self.short_id = short_id
end

def to_param
  short_id
end

Which means that my URLs look like myawesomeblog.com/posts/47cc6 which is a little better.

Emily
Just curious ... so how to MySql autoincrement ids work in replication?
concept47
I believe MySQL is much more aggressive about replication. Mongo works on an "eventually consistent" model. I haven't looked in to this in much depth, but there's a number of screencasts out there on Mongo replication that may shed some more light on the issue.
Emily