从Mongo获取BinData UUID作为字符串

Dav*_*ale 45 mongodb

我目前在Mongo中存储了一些ID作为UUID(处理所必需的).他们像这样返回:

"_id" : new BinData(3, "JliB6gIMRuSphAD2KmhzgQ==")
Run Code Online (Sandbox Code Playgroud)

将此值转换为字符串进行调试的简单方法是什么?

需要明确的是 - 应用程序可以很好地处理数据.我只需要一种快速从Mongo获取实际UUID的方法.

Rob*_*tam 73

您的问题的答案比您期望的更复杂!它很复杂的主要原因是,由于历史原因(不幸的是),不同的驱动程序使用不同的字节顺序将UUID写入数据库.您没有提到您正在使用的驱动程序,但我将使用C#驱动程序作为示例.

假设我使用以下代码插入文档:

var guid = new Guid("00112233-4455-6677-8899-aabbccddeeff");
collection.Insert(new BsonDocument {
    { "_id", guid },
    { "x", 1 }
});
Run Code Online (Sandbox Code Playgroud)

如果我然后使用Mongo shell检查文档,它看起来像这样:

> db.test.findOne()
{ "_id" : BinData(3,"MyIRAFVEd2aImaq7zN3u/w=="), "x" : 1 }
>
Run Code Online (Sandbox Code Playgroud)

Mongo shell有一个名为hex的内置函数,可用于将二进制值显示为十六进制字符串:

> var doc = db.test.findOne()
> doc._id.hex()
33221100554477668899aabbccddeeff
>
Run Code Online (Sandbox Code Playgroud)

仔细观察:十六进制字符串的字节顺序与C#程序中使用的原始UUID值不匹配.那是因为C#驱动程序使用了Guid类的Microsoft的ToByteArray方法返回的字节顺序(遗憾地以奇怪的顺序返回字节,这个事实在很多个月都没有被发现).其他司机有自己的特质.

为了解决这个问题,我们有一些用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 }
>
Run Code Online (Sandbox Code Playgroud)

在此示例中,toCSUUID函数用于将BinData值显示为CSUUID,CSUUID函数用于使用C#驱动程序的字节排序约定为UUID创建BinData值,以便我们可以查询UUID.其他驱动程序有类似的功能(toJUUID,toPYUUID,JUUID,PYUUID).

将来的某一天,所有驱动程序都将使用标准字节顺序标准化新的二进制子类型4.在此期间,您必须使用适当的辅助函数来匹配您正在使用的任何驱动程序.

  • 甜蜜的圣鬼这是荒谬的.谢谢你. (4认同)
  • 如果您正在使用RoboMongo,本文将告诉您如何启用uuidhelpers.js:http://robomongo.org/articles/uuids.html (2认同)
  • 这是一个旧的答案,所以这是可以理解的,但我只是想节省人们的时间,并说 hex() 函数似乎不再受支持。我正在寻找替代方案。 (2认同)

Tod*_*odd 9

在查询之前使用此功能:

function ToGUID(hex) {
    var a = hex.substr(6, 2) + hex.substr(4, 2) + hex.substr(2, 2) + hex.substr(0, 2);
    var b = hex.substr(10, 2) + hex.substr(8, 2);
    var c = hex.substr(14, 2) + hex.substr(12, 2);
    var d = hex.substr(16, 16);
    hex = a + b + c + d;
    var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
    return '"' + uuid + '"';
}

var id = new BinData(3, "JliB6gIMRuSphAD2KmhzgQ==");
ToGUID(id.hex());
Run Code Online (Sandbox Code Playgroud)

结果: "ea815826-0c02-e446-a984-00f62a687381"


Leo*_*rdo 6

如果您使用的是 Java spring-data,则可以使用此算法:

function ToUUID(hex) {
    var msb = hex.substr(0, 16);
    var lsb = hex.substr(16, 16);
    msb = msb.substr(14, 2) + msb.substr(12, 2) + msb.substr(10, 2) + msb.substr(8, 2) + msb.substr(6, 2) + msb.substr(4, 2) + msb.substr(2, 2) + msb.substr(0, 2);
    lsb = lsb.substr(14, 2) + lsb.substr(12, 2) + lsb.substr(10, 2) + lsb.substr(8, 2) + lsb.substr(6, 2) + lsb.substr(4, 2) + lsb.substr(2, 2) + lsb.substr(0, 2);
    hex = msb + lsb;
    var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);

    return uuid;
}
Run Code Online (Sandbox Code Playgroud)