2011-11-23 11 views
38

Actualmente tengo algunos identificadores almacenados en Mongo como UUID (necesarios para el procesamiento). Se devuelven así:Obtener UUID de BinData de Mongo como cadena

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

¿Cuál sería una manera fácil de convertir este valor en una cadena para la depuración?

Para que quede claro, la aplicación puede manejar bien los datos. Solo necesito una forma de obtener el UUID real de Mongo rápidamente.

Respuesta

64

¡La respuesta a su pregunta es más complicada de lo que cabría esperar! La razón principal por la que es complicado es que, por razones históricas (desafortunadamente), diferentes controladores han escrito UUID en la base de datos utilizando diferentes órdenes de bytes. No menciona qué controlador está usando, pero usaré el controlador C# como ejemplo.

Supongamos que utilizar el siguiente código para insertar un documento:

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

Si a continuación, examino el documento mediante la consola mongo, que se parece a esto:

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

La cáscara Mongo tiene una función incorporada llamada hex que puede usar para mostrar el valor binario como una cadena hexadecimal:

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

Mire con atención: el orden de bytes de la cadena hexadecimal no coincide con el valor UUID original utilizado en el programa C#. Esto se debe a que el controlador C# usa el orden de bytes devuelto por el método ToByteArray de Microsoft de la clase Guid (que tristemente devuelve los bytes en un orden extraño, hecho que no se descubrió durante muchos meses). Otros conductores tienen sus propias idiosincrasias.

Para ayudar con esto tenemos algunas funciones auxiliares escritas en Javascript que se pueden cargar en el shell de Mongo. Se definen en este archivo:

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

La consola mongo se puede contar para procesar un archivo, ya que se pone en marcha, proporcionando el nombre del archivo en la línea de comandos (junto con el argumento --shell) . Después de haber cargado este archivo, tenemos acceso a una serie de funciones auxiliares para crear y visualizar valores de BinData que son UUID. Por ejemplo:

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

En este ejemplo, la función toCSUUID se utiliza para mostrar un valor BinData como CSUUID y la función CSUUID se utiliza para crear un valor BinData para un UUID utilizando las convenciones de orden de bytes del # de conducir C para que podamos puede consultar en un UUID. Hay funciones similares para los otros controladores (para JUUID, toPYUUID, JUUID, PYUUID).

Algún día en el futuro, todos los controladores se estandarizarán en un nuevo subtipo 4 binario con un orden de bytes estándar. Mientras tanto, debes usar la función de ayuda adecuada que coincida con el controlador que estés utilizando.

+0

Eso es justo lo Estaba buscando, gracias! No tenía idea de la historia detrás de esto. –

+0

¿Soñé esto, o no solía ser otra forma de hacerlo? P.ej. '{" $ uuid ":" 00112233-4455-6677-8899-aabbccddeeff "}' – nilskp

+3

dulce fantasma sagrado esto es absurdo. Gracias de cualquier forma. –

2

Utilice esta función antes de su consulta:

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

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

0

Si está utilizando Java primavera-datos, puede utilizar este algoritmo:

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; 
} 
Cuestiones relacionadas