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