如何缩短Mongo ID以便更好地用于URLs?

14 投票
5 回答
4493 浏览
提问于 2025-04-16 07:31

我做了很多用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"

撰写回答