2011-11-23 27 views
38

Tôi hiện có một số id được lưu trữ trong Mongo dưới dạng UUID (cần thiết để xử lý). Họ được trả lại như sau:Nhận BinData UUID từ Mongo dưới dạng chuỗi

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

Điều gì sẽ là cách dễ dàng để biến giá trị này thành chuỗi để gỡ lỗi?

Chỉ cần rõ ràng - ứng dụng có thể xử lý tốt dữ liệu. Tôi chỉ cần một cách để có được UUID thực sự từ Mongo một cách nhanh chóng.

Trả lời

64

Câu trả lời cho câu hỏi của bạn phức tạp hơn mà bạn mong đợi! Lý do chính nó phức tạp là vì lý do lịch sử (không may) các trình điều khiển khác nhau đã viết UUID vào cơ sở dữ liệu bằng cách sử dụng các đơn đặt hàng byte khác nhau. Bạn không đề cập đến trình điều khiển nào bạn đang sử dụng, nhưng tôi sẽ sử dụng trình điều khiển C# làm ví dụ.

Giả sử tôi sử dụng đoạn mã sau để chèn một tài liệu:

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

Nếu tôi sau đó kiểm tra các tài liệu bằng cách sử dụng vỏ Mongo, nó trông như thế này:

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

Các Mongo vỏ có hàm dựng sẵn có tên hex mà bạn có thể sử dụng để hiển thị giá trị nhị phân dưới dạng chuỗi hex:

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

Xem xét cẩn thận: thứ tự byte của chuỗi hex không khớp với giá trị UUID ban đầu được sử dụng trong chương trình C#. Đó là bởi vì trình điều khiển C# sử dụng thứ tự byte được trả về bởi phương thức ToByteArray của Microsoft của lớp Guid (thứ đáng buồn trả về các byte theo thứ tự kì quái, thực tế không được phát hiện trong nhiều tháng). Các trình điều khiển khác có idiosyncracies riêng của họ.

Để trợ giúp với điều này, chúng tôi có một số chức năng trợ giúp được viết bằng Javascript có thể được tải vào trình bao Mongo. Chúng được định nghĩa trong tập tin này:

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

Vỏ Mongo có thể được cho biết để xử lý một tập tin khi nó bắt đầu lên bằng cách cung cấp tên của các tập tin trên dòng lệnh (cùng với lập luận --shell) . Sau khi tải tệp này, chúng tôi có quyền truy cập vào một số hàm trợ giúp để tạo và hiển thị các giá trị BinData là UUID. Ví dụ:

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

Trong ví dụ này các chức năng toCSUUID được sử dụng để hiển thị một giá trị BinData như một CSUUID và chức năng CSUUID được sử dụng để tạo ra một giá trị BinData cho một UUID sử dụng công ước byte đặt hàng C# bằng lái xe để chúng tôi có thể truy vấn trên UUID. Có các chức năng tương tự cho các trình điều khiển khác (toJUUID, toPYUUID, JUUID, PYUUID).

Một số ngày trong tương lai tất cả các trình điều khiển sẽ chuẩn hóa trên một loại phụ nhị phân mới 4 với thứ tự byte chuẩn. Trong khi chờ đợi, bạn phải sử dụng chức năng trợ giúp thích hợp phù hợp với bất kỳ trình điều khiển nào bạn đang sử dụng.

+0

Đó chỉ là những gì Tôi đang tìm kiếm, cảm ơn! Tôi không biết lịch sử đằng sau chuyện này. –

+0

Tôi đã mơ ước điều này, hoặc không có sử dụng để có một cách khác để làm điều đó? Ví dụ. '{" $ uuid ":" 00112233-4455-6677-8899-aabbccddeeff "}' – nilskp

+3

ma thánh ngọt ngào điều này là ngớ ngẩn. Cảm ơn bạn mặc dù. –

2

Sử dụng chức năng này trước khi truy vấn của bạn:

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

Kết quả: "ea815826-0c02-e446-a984-00f62a687381"

0

Nếu bạn đang sử dụng Java lò xo dữ liệu, bạn có thể sử dụng thuật toán này:

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; 
} 
Các vấn đề liên quan