2011-11-23 18 views
38

我目前在Mongo中存儲了一些作爲UUID(處理必需)的ID。他們得到這樣的回報:從Mongo獲取BinData UUID作爲字符串

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

什麼是將此值轉換爲字符串調試的簡單方法?

只是要清楚 - 應用程序可以處理好數據。我只需要一種快速從Mongo中獲取實際UUID的方法。

回答

64

您的問題的答案更復雜,你會期望!這很複雜的主要原因是由於歷史原因(不幸的是)不同的驅動程序使用不同的字節順序將UUID寫入數據庫。您沒有提及您使用的是哪個驅動程序,但我將使用C#驅動程序作爲示例。

假設我用下面的代碼中插入一個文件:

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

如果我再檢查使用蒙戈外殼文件,它看起來像這樣:

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

蒙戈外殼具有內置函數稱爲十六進制,可用於將二進制值顯示爲十六進制字符串:

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

仔細查看:十六進制字符串的字節順序與C#程序中使用的原始UUID值不匹配。這是因爲C#驅動程序使用Guid類的Microsoft ToByteArray方法返回的字節順序(可悲地,它以奇怪的順序返回字節,這個事實在很多個月中都沒有發現)。其他司機有他們自己的特質。

爲了幫助解決這個問題,我們使用Javascript編寫了一些可以加載到Mongo shell的幫助函數。他們在這個文件中定義:

​​

蒙戈外殼可以告訴處理文件,因爲它提供的命令行上的文件的名稱啓動(連同--shell參數) 。加載這個文件後,我們可以訪問許多幫助函數來創建和顯示UUID的BinData值。例如:

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功能是用來使用C#驅動程序的字節順序約定,以便創造一個UUID一個BinData值,我們可以在UUID上查詢。對於其他驅動程序(對於JUUID,toPYUUID,JUUID,PYUUID)也有類似的功能。

有朝一日,未來的所有驅動程序將標準化一個新的二進制子類型4與標準的字節順序。在此期間,您必須使用與您使用的驅動程序匹配的適當幫助函數。

+0

這正是我在找,謝謝!我不知道這背後的歷史。 –

+0

我有沒有想過這個,或者沒有用它來做另一種方法?例如。 '{「$ uuid」:「00112233-4455-6677-8899-aabbccddeeff」}' – nilskp

+3

甜聖潔的鬼這是荒謬的。謝謝你。 –

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"

0

如果您使用的是Java彈簧的數據,你可以用這個算法:

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