Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.9k views
in Technique[技术] by (71.8m points)

node.js - Converting mongodb Binary _id to LUUID using node

I'm trying to move data from mongodb to mysql

I used mongoexport in order to export the data from the mongodb database to .json files

When I browse my mongodb collection using robomongo I'm getting ids in a Legacy UUID format (something like LUUID("00018e06-1de9-aa45-afb5-a2bc00ed94f7") but in the exported .json files it appears this way: { "_id" : { "$binary" : "AAGOBh3pqkWvtaK8AO2U9w==", "$type" : "03" }, ...}

It there any way to convert the latter to the format I see in robomongo using Node.JS?

P.S I've seen many Q&A that reference Binary and BinData - but non of them have shown how to convert it

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

So, first off $binary and BinData are basically the same thing written/represented different ways. Using your example and this reference you can write it like so in the "Mongo Shell" mode:

BinData(3,"AAGOBh3pqkWvtaK8AO2U9w==")

Or in "strict" mode that becomes:

{ "$binary" : "AAGOBh3pqkWvtaK8AO2U9w==", "$type" : "03" }

Now, type 3 here actually refers to subtype 3 (of the binary type) per the BSON spec which means this is a "UUID (old)" subtype. Per the reference above, the string itself is actually a base64 representation of a binary string. Because of this (I am inferring) robomongo is basically converting the UUID and displaying it for you when you are browsing the data. Let's attempt to do that manually instead in the mongo shell, first by converting it to hex:

> var foo = BinData(3, "AAGOBh3pqkWvtaK8AO2U9w==")
> foo.hex()
00018e061de9aa45afb5a2bc00ed94f7

Now, let's plug that into a UUID constructor and see if it translates back:

> var uuid = new UUID("00018e061de9aa45afb5a2bc00ed94f7")
> uuid
BinData(3,"AAGOBh3pqkWvtaK8AO2U9w==")

And, it does - all robomongo is doing is adding some dashes for readability. Just for completeness, with your other example I will remove the dashes and create a UUID, show the BinData version and convert back:

> var bar = UUID("d72f21fe47808040ab3da1fb01045d3a")
> bar
BinData(3,"1y8h/keAgECrPaH7AQRdOg==")
> bar.hex()
d72f21fe47808040ab3da1fb01045d3a

Hence, what you need to do is convert between the base64 encoding in node yourself. I don't have a node.js environment to test, but it looks like that has been covered before elsewhere on the site.

EDIT:

This is a working function in Node.JS that converts the binary to Hex UUID:

function Bin2HexUUID(bin){
    var hex = new Buffer(bin, 'base64').toString('hex');
    return hex.replace(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, function (){
        return arguments[1]+"-"+arguments[2]+"-"+arguments[3]+"-"+arguments[4]+"-"+arguments[5];
    });
}

//use example
var binary_id = { "$binary" : "AAGOBh3pqkWvtaK8AO2U9w==", "$type" : "03" };
console.log(Bin2HexUUID(binary_id.$binary)); //00018e06-1de9-aa45-afb5-a2bc00ed94f7

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...