Подтвердить что ты не робот

Получить UUID BinData от Mongo как строку

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

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

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

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

4b9b3361

Ответ 1

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

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

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 }
>

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

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

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

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

Ответ 2

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

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"