我目前有一些ID作为UUID存储在Mongo中(处理所需).他们得到的回报如下:
"_id" : new BinData(3, "JliB6gIMRuSphAD2KmhzgQ==")
将该值转换为字符串以进行调试的简单方法是什么?
需要明确的是,应用程序可以很好地处理数据.我只需要一种快速从Mongo获取实际UUID的方法.
我目前有一些ID作为UUID存储在Mongo中(处理所需).他们得到的回报如下:
"_id" : new BinData(3, "JliB6gIMRuSphAD2KmhzgQ==")
将该值转换为字符串以进行调试的简单方法是什么?
需要明确的是,应用程序可以很好地处理数据.我只需要一种快速从Mongo获取实际UUID的方法.
你问题的答案比你想象的要复杂!其复杂的主要原因是,由于历史原因(不幸的是),不同的驱动程序使用不同的字节顺序将UUID写入数据库.你没有提到你正在使用哪个驱动程序,但我将以C#驱动程序为例.
假设我使用以下代码插入文档:
var guid = new Guid("00112233-4455-6677-8899-aabbccddeeff");
collection.Insert(new BsonDocument {
{ "_id", guid },
{ "x", 1 }
});
然后,如果我使用Mongo shell判断文档,它看起来是这样的:
> db.test.findOne()
{ "_id" : BinData(3,"MyIRAFVEd2aImaq7zN3u/w=="), "x" : 1 }
>
Mongo shell有一个名为hex的内置函数,可用于将二进制值显示为十六进制字符串:
> var doc = db.test.findOne()
> doc._id.hex()
33221100554477668899aabbccddeeff
>
仔细看:十六进制字符串的字节顺序与C#程序中使用的原始UUID值不匹配.这是因为C#驱动程序使用Guid类的Microsoft ToByteArray方法返回的字节顺序(遗憾的是,它以奇怪的顺序返回字节,这一事实已经好几个月没有被发现).其他司机也有自己的trait .
为了解决这个问题,我们有一些用Javascript编写的助手函数,可以加载到Mongo shell中.它们在该文件中定义:
https://github.com/mongodb/mongo-csharp-driver/blob/master/uuidhelpers.js
通过在命令行中提供文件名(以及--shell参数),可以告诉Mongo shell在启动时处理文件.加载此文件后,我们可以访问许多帮助函数来创建和显示属于UUID的BinData值.例如:
C:\mongodb\mongodb-win32-x86_64-2.0.1\bin>mongo --shell uuidhelpers.js
MongoDB shell version: 2.0.1
connecting to: test
type "help" for help
> var doc = db.test.findOne()
> doc._id.toCSUUID()
CSUUID("00112233-4455-6677-8899-aabbccddeeff")
> db.test.find({_id : CSUUID("00112233-4455-6677-8899-aabbccddeeff")})
{ "_id" : BinData(3,"MyIRAFVEd2aImaq7zN3u/w=="), "x" : 1 }
>
在本例中,tocsuid函数用于将BinData值显示为CSUUID,CSUUID函数用于使用C#driver的字节排序约定为UUID创建BinData值,以便我们可以查询UUID.其他驱动程序(toJUUID、toPYUUID、JUUID、PYUUID)也有类似的功能.
将来的某一天,所有驱动程序都将标准化为一个新的二进制子类型4,具有标准字节顺序.同时,你必须使用合适的助手函数来匹配你正在使用的任何驱动程序.