MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Obtenha BinData UUID do Mongo como string


A resposta à sua pergunta é mais complicada do que você esperaria! A principal razão pela qual é complicado é que, por razões históricas (infelizmente), drivers diferentes gravaram UUIDs no banco de dados usando ordens de bytes diferentes. Você não menciona qual driver está usando, mas usarei o driver C# como exemplo.

Suponha que eu use o seguinte código para inserir um documento:
var guid = new Guid("00112233-4455-6677-8899-aabbccddeeff");
collection.Insert(new BsonDocument {
    { "_id", guid },
    { "x", 1 }
});

Se eu examinar o documento usando o shell do Mongo, ele ficará assim:
> db.test.findOne()
{ "_id" : BinData(3,"MyIRAFVEd2aImaq7zN3u/w=="), "x" : 1 }
>

O shell do Mongo tem uma função interna chamada hex que você pode usar para exibir o valor binário como uma string hexadecimal:
> var doc = db.test.findOne()
> doc._id.hex()
33221100554477668899aabbccddeeff
>

Observe com atenção:a ordem de bytes da string hexadecimal não corresponde ao valor UUID original usado no programa C#. Isso porque o driver C# usa a ordem de bytes retornada pelo método ToByteArray da Microsoft da classe Guid (que infelizmente retorna os bytes em uma ordem bizarra, fato que não foi descoberto por muitos meses). Outros motoristas têm suas próprias idiossincrasias.

Para ajudar com isso, temos algumas funções auxiliares escritas em Javascript que podem ser carregadas no shell do Mongo. Eles são definidos neste arquivo:

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

O shell do Mongo pode ser instruído a processar um arquivo quando ele é inicializado, fornecendo o nome do arquivo na linha de comando (junto com o argumento --shell). Tendo carregado este arquivo, temos acesso a várias funções auxiliares para criar e exibir valores BinData que são UUIDs. Por exemplo:
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 }
>

Neste exemplo, a função toCSUUID é usada para exibir um valor BinData como um CSUUID e a função CSUUID é usada para criar um valor BinData para um UUID usando as convenções de ordenação de bytes do driver C# para que possamos consultar um UUID. Existem funções semelhantes para os outros drivers (toJUUID, toPYUUID, JUUID, PYUUID).

Algum dia no futuro, todos os drivers serão padronizados em um novo subtipo binário 4 com uma ordem de bytes padrão. Enquanto isso, você deve usar a função auxiliar apropriada que corresponda a qualquer driver que você esteja usando.