I've built a number of python driven sites that utilize mongodb as a database backend and am very happy with it's ObjectId system, however, I'd love to be able encode the ids in a shorter fashion without building a mapping collection or utilizing a url-shortener service.
Suggestions? Success stories?
You could compress them as Base62 numbers. This doesn't save a lot of space, but it does save you a few bytes per ID. My example's Ruby, but similar usage in Python wouldn't be hard.
ree-1.8.7-2010.02 > User.first._id.to_s
=> "4c76f3dd98db74697500003b"
ree-1.8.7-2010.02 > User.first._id.to_s.to_i(16).base62_encode
=> "uMarF7LmpY3bNOSn"
Heh, I recently wanted the exact same thing myself.
What I've ended up doing is giving every document that needs one a "public id" that is unique (like the ObjectId), but that is just an auto-incrementing number (so it'll take a while before the numbers get huge, and even longer if they're hex-encoded). This way, I can use the ObjectId internally (which I suspect is faster), and lookup externally referenced documents using their public id.
Note that there is a little performance hit when creating these public ids since each one requires an atomic update to a document (so you should only use them where you need them).
The key to creating an auto-incrementing number is MongoDB's findAndModify
command to both increment a value and return the old value in a single atomic operation.
Since you're using Python, and so am I, here is the code that I'm currently using (note that it's not in production yet):
from pymongo import Connection
from pymongo.son import SON
db = Connection().mydatabase
PUBLIC_ID_COLLECTION = 'next_public_id'
def next_public_id():
result = db.command(SON({ 'findandmodify': PUBLIC_ID_COLLECTION },
query = { '_id': 'manager' },
update = { '$inc': { 'next_public_id': 1 } },
upsert = True # Insert if not already existing
))
manager = result['value']
return manager.get('next_public_id', 0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With