【问题标题】:Why does PyMongo encode uuid.uuid1() as a BSON::Binary?为什么 PyMongo 将 uuid.uuid1() 编码为 BSON::Binary?
【发布时间】:2012-08-15 08:57:04
【问题描述】:

我正在为 Mongo 中的所有文档添加一个值为 uuid.uuid1()(来自 python uuid 模块)的“GUID”键。我注意到它们不是作为字符串存储的,而是作为 BSON::Binary 类型存储的。我已经做了一些谷歌搜索,但我仍然不明白这个序列化的目的/优势是什么。有人可以解释吗?我应该在存储之前将 uuid.uuid1() 转换为字符串吗?如何通过 db.myCol.find({ 'GUID' : aString }) 之类的 GUID 值使用字符串 find()?

【问题讨论】:

    标签: python mongodb uuid pymongo bson


    【解决方案1】:

    Python uuid 的默认序列化在 BSON spec 中使用 UUID 二进制表示,因为这样可以确保范围查询的排序一致,并且还使用更少的数据/索引存储。

    例如,这三个字符串在十六进制中是等价的:

    5d78ad35ea5f11e1a183705681b29c47
    5D78AD35EA5F11E1A183705681B29C47
    5d78ad35ea5f11e1A183705681B29C47
    

    ..但作为字符串有不同的排序顺序:

    > db.uuidsort.find().sort({_id:1})
    { "_id" : "5D78AD35EA5F11E1A183705681B29C47" }
    { "_id" : "5d78ad35ea5f11e1A183705681B29C47" }
    { "_id" : "5d78ad35ea5f11e1a183705681b29c47" }
    

    比较 bson 大小:

    > db.uuidtest.find()
    { "_id" : BinData(3,"XXitNepfEeGhg3BWgbKcRw==") }
    { "_id" : "5d78ad35ea5f11e1a183705681b29c47" }
    
    > Object.bsonsize(db.uuidtest.findOne({_id: BinData(3,"XXitNepfEeGhg3BWgbKcRw==")}))
    31
    
    > Object.bsonsize(db.uuidtest.findOne({_id: "5d78ad35ea5f11e1a183705681b29c47"}))
    47
    

    如果您确实想作为字符串插入,可以使用UUID.hex 来获得等效的 32 个字符的字符串:

    >>> db.uuidtest.insert({'_id': uuid.hex})
    '5d78ad35ea5f11e1a183705681b29c47'
    

    如果您想从 Python 中按字符串查找 UUID,可以使用 uuid.UUID 方法:

    >>> db.uuidtest.find_one({'_id':uuid.UUID('5d78ad35ea5f11e1a183705681b29c47')})
    {u'_id': UUID('5d78ad35-ea5f-11e1-a183-705681b29c47')}
    

    如果您想从mongo shell 中按字符串查找 UUID,则有一个 UUID() 助手:

    > db.uuidtest.find({_id:UUID('5d78ad35ea5f11e1a183705681b29c47')})
    { "_id" : BinData(3,"XXitNepfEeGhg3BWgbKcRw==") }
    

    注意:还有一些其他 UUID 子类型可用于与其他驱动程序版本的互操作性,如 API docs for bson.binary 中所述。

    【讨论】:

    • 什么是 BinData,它的 2 个参数代表什么?
    • @yourfriendzak:你的意思是来自 shell 还是来自 Python?从 mongo shell 添加了一个示例。
    • BinData 是 BSON 类型(请参阅bsonspec.org)。参数表示编码的子类型(例如,3 是旧的默认 UUID 格式;较新的驱动程序默认为 4)。子类型允许驱动程序正确解码二进制文件。
    • 谢谢 Stennie,很好的答案
    • 另外,我注意到 str( mongoDoc['GUID'] ) 也适用于 GUID : a BSON:UUID
    猜你喜欢
    • 2013-03-26
    • 2014-11-03
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 2016-04-06
    • 2015-07-31
    • 1970-01-01
    • 2015-09-10
    相关资源
    最近更新 更多