如何缩短Mongo ID以便更好地用于URLs?
我做了很多用Python搭建的网站,这些网站使用MongoDB作为数据库,觉得它的ObjectId系统非常好。不过,我希望能把这些ID缩短一些,而不想建立一个映射表或者使用网址缩短服务。
有没有什么建议?或者成功的案例?
5 个回答
1
如果你想保留原来的值,其实没有什么好的办法。你可以尝试对它进行编码,但变小的可能性几乎没有。你也可以用哈希处理,但这样就无法还原成原来的值了。
如果这是一个必须要做到的事情,我建议你可以创建一个查找表或者一个集合,用一个小的递增数字来引用Mongo数据库中的条目。
7
嘿,我最近也想要一样的东西。
我现在的做法是给每个需要的文档一个独特的“公共ID”,这个ID就像ObjectId一样唯一,但它只是一个自动递增的数字(所以在数字变得很大之前会需要一段时间,如果用十六进制编码的话,所需时间会更长)。这样,我可以在内部使用ObjectId(我觉得这样可能更快),而通过公共ID来查找外部引用的文档。
需要注意的是,创建这些公共ID时会有一点性能损失,因为每个ID都需要对文档进行一次原子更新(所以你应该只在需要的地方使用它们)。
创建自动递增数字的关键是MongoDB的findAndModify
命令,它可以在一次原子操作中同时增加一个值并返回旧值。
因为你在用Python,我也是,所以这里是我目前使用的代码(注意这还没有投入生产):
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)
12
你可以把它们压缩成Base62格式的数字。虽然这样并不能节省很多空间,但每个ID可以节省几个字节。我这里用的是Ruby语言,但在Python中做类似的操作也不难。
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"