我已经构建了许多使用mongodb作为数据库后端的python驱动站点,并且对它的ObjectId系统非常满意,但是,我希望能够以更短的方式编码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"
答案 1 :(得分:7)
我最终做的是给每个需要一个独特的“公共ID”的文档(比如ObjectId),但这只是一个自动递增的数字(所以它需要一段时间才会如果它们是十六进制编码的话,数字会变得很大,甚至更长。这样,我可以在内部使用ObjectId(我怀疑它更快),并使用它们的公共ID查找外部引用的文档。
请注意,创建这些公共ID时会有一点性能损失,因为每个公共ID需要对文档进行原子更新(因此您只应在需要它们的地方使用它们)。
创建自动递增数字的关键是MongoDB的findAndModify
command,它们都会递增一个值并在单个原子操作中返回旧值。
由于你使用的是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)
答案 2 :(得分:1)
如果您试图保留原始值,那么确实没有好办法。你可以编码它,但它的可能性更小是最小的。你可以哈希它,但那时它是不可逆的。
如果这是一个要求,我可能会建议创建一个查找表或集合,其中一个小的增量数字引用Mongo集合中的条目。
答案 3 :(得分:1)
我刚才在mongodb的邮件列表上提到了这个话题。看看它是否可以帮到你。
答案 4 :(得分:0)
如果您可以生成自动递增的唯一数字,则绝对不需要将ObjectId用于_id。在分布式环境中执行此操作很可能比使用ObjectId更昂贵。这是你的权衡。