Получить BinData UUID из Mongo в виде строки - PullRequest
44 голосов
/ 23 ноября 2011

У меня в настоящее время есть некоторые идентификаторы, хранящиеся в Mongo как UUID (необходимые для обработки).Они возвращаются следующим образом:

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

Какой простой способ превратить это значение в строку для отладки?

Просто чтобы прояснить - приложение может нормально обрабатывать данные.Мне просто нужен способ быстро получить фактический UUID от Монго.

Ответы [ 4 ]

70 голосов
/ 24 ноября 2011

Ответ на ваш вопрос сложнее, чем вы ожидаете! Основная причина, по которой это сложно, заключается в том, что по историческим причинам (к сожалению) разные драйверы записывают UUID в базу данных, используя разные порядки байтов. Вы не упоминаете, какой драйвер вы используете, но я буду использовать драйвер C # в качестве примера.

Предположим, я использую следующий код для вставки документа:

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

Если я затем проверю документ с помощью оболочки Mongo, он будет выглядеть следующим образом:

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

Оболочка Mongo имеет встроенную функцию hex, которую можно использовать для отображения двоичного значения в виде шестнадцатеричной строки:

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

Посмотрите внимательно: порядок байтов шестнадцатеричной строки не соответствует исходному значению UUID, используемому в программе C #. Это связано с тем, что драйвер C # использует порядок байтов, возвращаемый методом Microsoft ToByteArray класса Guid (который, к сожалению, возвращает байты в странном порядке, что не было обнаружено в течение многих месяцев). У других водителей есть свои особенности.

Чтобы помочь с этим, у нас есть несколько вспомогательных функций, написанных на Javascript, которые можно загрузить в оболочку Mongo. Они определены в этом файле:

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

Оболочке Mongo можно указать обработать файл при запуске, указав имя файла в командной строке (вместе с аргументом --shell). Загрузив этот файл, мы имеем доступ к ряду вспомогательных функций для создания и отображения значений BinData, которые являются UUID. Например:

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 используется для создания значения BinData для UUID с использованием соглашений о порядке следования байтов драйвера C #, чтобы мы могли запрашивать UUID. Существуют аналогичные функции для других драйверов (toJUUID, toPYUUID, JUUID, PYUUID).

Когда-нибудь в будущем все драйверы будут стандартизированы для нового двоичного подтипа 4 со стандартным порядком байтов. Тем временем вы должны использовать соответствующую вспомогательную функцию, которая соответствует любому используемому вами драйверу.

8 голосов
/ 15 июня 2017

Используйте эту функцию перед запросом:

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

Результат: "ea815826-0c02-e446-a984-00f62a687381"

2 голосов
/ 18 января 2018

Если вы используете 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;
}
0 голосов
/ 21 сентября 2018
def binaryToUUID(byte: Array[Byte]): String = {

  if (byte == null) null

  else {
    val bb = ByteBuffer.wrap(byte)
    new UUID(bb.getLong, bb.getLong()).toString
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...