从Mongo获取BinData UUID作为字符串

时间:2011-11-23 14:47:29

标签: mongodb

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

"_id" : new BinData(3, "JliB6gIMRuSphAD2KmhzgQ==")

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

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

4 个答案:

答案 0 :(得分:68)

您的问题的答案比您期望的更复杂!它很复杂的主要原因是,由于历史原因(不幸的是),不同的驱动程序使用不同的字节顺序将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方法返回的字节顺序(遗憾地以奇怪的顺序返回字节,这个事实在很多个月内都没有被发现)。其他司机有自己的特质。

为了帮助解决这个问题,我们有一些用Javascript编写的辅助函数可以加载到Mongo shell中。它们在此文件中定义:

https://github.com/mongodb/mongo-csharp-driver/blob/master/uuidhelpers.js

可以告诉Mongo shell在启动时通过在命令行上提供文件名(以及--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 }
>

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

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

答案 1 :(得分:8)

Use this function before your query:

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());

Result: "ea815826-0c02-e446-a984-00f62a687381"

答案 2 :(得分:2)

如果您使用的是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;
}

答案 3 :(得分:0)

def binaryToUUID(byte: Array[Byte]): String = {

  if (byte == null) null

  else {
    val bb = ByteBuffer.wrap(byte)
    new UUID(bb.getLong, bb.getLong()).toString
  }
}