web-dev-qa-db-fra.com

Obtenir BinData UUID de Mongo sous forme de chaîne

J'ai actuellement des identifiants stockés dans Mongo en tant qu'UUID (nécessaires au traitement). Ils sont retournés comme ceci:

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

Quel serait un moyen facile de transformer cette valeur en une chaîne de débogage?

Soyons clairs: l’application peut gérer les données avec précision. J'ai juste besoin d'un moyen d'obtenir rapidement le UUID réel de Mongo.

40
David Neale

La réponse à votre question est plus compliquée que vous ne le pensez! La principale raison de cette complexité est que, pour des raisons historiques (malheureusement), différents pilotes ont écrit des UUID dans la base de données en utilisant différents ordres d'octet. Vous ne mentionnez pas le pilote que vous utilisez, mais j'utiliserai le pilote C # comme exemple.

Supposons que j'utilise le code suivant pour insérer un document:

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

Si j'examine ensuite le document à l'aide du shell Mongo, il se présente comme suit:

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

Le shell Mongo a une fonction intégrée appelée hex que vous pouvez utiliser pour afficher la valeur binaire sous forme de chaîne hexagonale:

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

Regardez attentivement: l'ordre des octets de la chaîne hexadécimale ne correspond pas à la valeur UUID d'origine utilisée dans le programme C #. En effet, le pilote C # utilise l'ordre des octets renvoyé par la méthode ToByteArray de la classe Guid de Microsoft (qui renvoie malheureusement les octets dans un ordre bizarre, ce qui n'a pas été découvert depuis de nombreux mois). Les autres conducteurs ont leurs propres particularités.

Pour vous aider, nous avons des fonctions d’aide écrites en Javascript qui peuvent être chargées dans le shell Mongo. Ils sont définis dans ce fichier:

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

On peut dire à Mongo Shell de traiter un fichier au démarrage en fournissant le nom du fichier sur la ligne de commande (avec l’argument --Shell). Après avoir chargé ce fichier, nous avons accès à un certain nombre de fonctions d’aide permettant de créer et d’afficher des valeurs BinData qui sont des UUID. Par exemple:

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

Dans cet exemple, la fonction toCSUUID est utilisée pour afficher une valeur BinData en tant que CSUUID et la fonction CSUUID est utilisée pour créer une valeur BinData pour un UUID à l'aide des conventions de classement des octets du pilote C # afin de pouvoir interroger un UUID. Il existe des fonctions similaires pour les autres pilotes (toJUUID, toPYUUID, JUUID, PYUUID).

Un jour, tous les pilotes adopteront un nouveau sous-type binaire 4 avec un ordre d'octets standard. En attendant, vous devez utiliser la fonction d'assistance appropriée qui correspond à tout pilote que vous utilisez.

68
Robert Stam

Utilisez cette fonction avant votre requête:

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

Résultat: "ea815826-0c02-e446-a984-00f62a687381"

6
Todd

Si vous utilisez des données de printemps Java, vous pouvez utiliser cet algorithme:

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;
}
2
Leonardo
def binaryToUUID(byte: Array[Byte]): String = {

  if (byte == null) null

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