为什么PyMongo将uuid.uuid1()编码为BSON :: Binary?

时间:2012-08-19 23:09:52

标签: python mongodb uuid pymongo bson

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

1 个答案:

答案 0 :(得分:4)

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

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

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中所述。