Journeyman
Journeyman

Reputation: 10271

How do I use a guid in a mongodb shell query

When using the MongoDB shell, how do I use a guid datatype (which I have used as the _id in my collection).

The following format doesn't work:

>db.person.find({"_id","E3E45566-AFE4-A564-7876-AEFF6745FF"});

Thanks.

Upvotes: 35

Views: 52756

Answers (6)

fafl
fafl

Reputation: 7385

New answer to an old question, but none of the code examples in this thread worked for me.

It looks like BinData type 03 has multiple subtypes, depending on the language. Check the mongo-java-driver code here.

For Java, the UUID is split into two halves and then each half is flipped.

This python code can translate UUIDs to BinData() type 03 subtype JAVA_LEGACY and back to UUID:

import base64
import uuid

def mongo_bin_data_to_uuid(bin_data_base64):
    raw_bytes = base64.b64decode(bin_data_base64)
    flipped_bytes = raw_bytes[7::-1] + raw_bytes[-1:7:-1]
    return str(uuid.UUID(bytes=flipped_bytes))

def uuid_to_mongo_bin_data(uuid_string):
    raw_bytes = uuid.UUID(uuid_string).bytes
    flipped_bytes = raw_bytes[7::-1] + raw_bytes[-1:7:-1]
    return base64.b64encode(flipped_bytes).decode()

The result of

uuid_to_mongo_bin_data("E3E45566-AFE4-A564-7876-AEFF6745FF00")

is

"ZKXkr2ZV5OMA/0Vn/652eA=="

The query then looks like:

>db.person.find({"_id", BinData(03, "ZKXkr2ZV5OMA/0Vn/652eA==")});

Upvotes: 1

Vipin
Vipin

Reputation: 877

You can fix this issue by using split() and join() workaround:

for instance if I use "E3E45566-AFE4-A564-7876-AEFF6745FF" hex value with - inside UUID() function, it does not return BinData in mongo so please try removing all the - before passing to UUID function.

db.person.find({"_id":UUID("E3E45566-AFE4-A564-7876-AEFF6745FF".split("-").join(''))});

Or by defining a variable to do it in multiple line:

var uuid = UUID("E3E45566-AFE4-A564-7876-AEFF6745FF".split("-").join(''))
db.person.find({"_id":uuid});

or by creating a simple function:

function BUUID(uuid){
    var str = uuid.split("-").join('');
    return new UUID(str);
}
db.person.find({"_id": BUUID("E3E45566-AFE4-A564-7876-AEFF6745FF")}).pretty();

Upvotes: 0

cama
cama

Reputation: 31

I know it's an old issue, but without any additional needs you can use this one:

find({_id:UUID('af64ab4f-1098-458a-a0a3-f0f6c93530b7')})

Upvotes: 1

Todd
Todd

Reputation: 1081

You could use the following js function in front of your query like so:

function LUUID(uuid) {
    var hex = uuid.replace(/[{}-]/g, ""); // removes extra characters
    return new UUID(hex); //creates new UUID
}

db.person.find({"_id" : LUUID("E3E45566-AFE4-A564-7876-AEFF6745FF"});

You could save the function in .js file and load it or open it before you make your query and if you copy the value from your results you should rename the function with:

  • LUUID for Legacy UUID
  • JUUID for Java encoding
  • NUUID for .net encoding
  • CSUUID for c# encoding
  • PYUUID for python encoding

Upvotes: 19

Edward Weinert
Edward Weinert

Reputation: 543

You can use easily:

.find({ "_id" : CSUUID("E3E45566-AFE4-A564-7876-AEFF6745FF")})

Upvotes: 37

Robert Stam
Robert Stam

Reputation: 12187

You have to compare the _id value against an instance of BinData (not against a string). Unfortunately the BinData constructor takes a Base64 string instead of a hex string.

Your GUID value is missing two hex digits at the end, so for the purposes of this example I will assume they are "00". The following values are equivalent:

hex: "E3E45566-AFE4-A564-7876-AEFF6745FF00" (ignoring dashes)

base64: "ZlXk4+SvZKV4dq7/Z0X/AA=="

So your query should be:

>db.person.find({_id : new BinData(3, "ZlXk4+SvZKV4dq7/Z0X/AA==")})

I am assuming that the binary subtype was correctly set to 3. If not, what driver was used to create the data?

Upvotes: 20

Related Questions