mongodb 从 Mongo 获取 BinData UUID 作为字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8244110/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 12:20:19  来源:igfitidea点击:

Get BinData UUID from Mongo as string

mongodb

提问by David Neale

I currently have some ids stored in Mongo as UUIDs (necessary for processing). They get returned like this:

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

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

What would be an easy way to turn this value into a string for debugging?

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

Just to be clear - the application can handle the data fine. I just need a way to get the actual UUID from Mongo quickly.

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

回答by Robert Stam

The answer to your question is more complicated that you would expect! The main reason it's complicated is that for historical reasons (unfortunately) different drivers have written UUIDs to the database using different byte orders. You don't mention which driver you are using, but I'll use the C# driver as an example.

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

Suppose I use the following code to insert a document:

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

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

If I then examine the document using the Mongo shell, it looks like this:

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

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

The Mongo shell has a built-in function called hex that you can use to display the binary value as a hex string:

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

> var doc = db.test.findOne()
> doc._id.hex()
33221100554477668899aabbccddeeff
>

Look carefully: the byte order of the hex string doesn't match the original UUID value used in the C# program. That's because the C# driver uses the byte order returned by Microsoft's ToByteArray method of the Guid class (which sadly returns the bytes in a bizarre order, which fact was not discovered for many months). Other drivers have their own idiosyncracies.

仔细查看:十六进制字符串的字节顺序与 C# 程序中使用的原始 UUID 值不匹配。那是因为 C# 驱动程序使用由 Microsoft 的 Guid 类的 ToByteArray 方法返回的字节顺序(遗憾的是,它以一种奇怪的顺序返回字节,这个事实已经好几个月没有被发现了)。其他司机有他们自己的特质。

To help out with this we have some helper functions written in Javascript that can be loaded into the Mongo shell. They are defined in this file:

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

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

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

The Mongo shell can be told to process a file as it starts up by providing the name of the file on the command line (along with the --shell argument). Having loaded this file we have access to a number of helper functions to create and display BinData values that are UUIDs. For example:

通过在命令行上提供文件名(以及 --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 }
>

In this example the toCSUUID function is used to display a BinData value as a CSUUID and the CSUUID function is used to create a BinData value for a UUID using the C# driver's byte ordering conventions so that we can query on a UUID. There are similar functions for the other drivers (toJUUID, toPYUUID, JUUID, PYUUID).

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

Some day in the future all drivers will standardize on a new binary subtype 4 with a standard byte order. In the meantime you have to use the appropriate helper function that matches whatever driver you are using.

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

回答by Todd

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"

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

回答by Leonardo

If you are using Java spring-data, you can use this algorithm:

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

回答by knowledge_seeker

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

  if (byte == null) null

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