Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB[Java] : How do I query a stored UUID in byte[ ] format?

I am trying to query a java.util.UUID stored in my MongoDB, using a byte[] that corresponds to the same string the stored UUID is based on.

I've seen that the Mongo Driver automatically converts the UUID to bytes and stores it as a BinData(subtype, ). Here's the code I used to save a UUID:

        UUID originalUUID= UUID.fromString("7ee973c0-54b5-11e4-aaed-0002a5d5c51b");
        MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
        DB db = mongoClient.getDB("test");
        DBCollection coll = db.getCollection("test");

        BasicDBObject query = new BasicDBObject("_id", originalUUID);
        coll.save(query);

I know we can easily retrieve this document with a UUID object as the value in a BasicDBObject, but I would like to use a byte[] instead. After all, it's gotta be bytes in my Mongo right? I know a few complications arise with Java messing up the byte-order before sending it off to Mongo, but I haven't been able to get it to work. My code for retrieval is here:

        String stringOne = "7ee973c0-54b5-11e4-aaed-0002a5d5c51b"; 
        // It's the same UUID String

        BasicDBObject find = new BasicDBObject("_id", stringOne.getBytes());

        DBCursor cursor = null;
        cursor = coll.find(find);
        while(cursor.hasNext()){
            BasicDBObject dbObject = (BasicDBObject)cursor.next();
            byte[] received = (byte[])dbObject.get("_id");
            System.out.println(new String(received));
        }

I've also tried Little Endian encoding like this:

        byte[] bytes = new byte[16];
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        bb.order(ByteOrder.LITTLE_ENDIAN);

        bb.putLong(originalUUID.getMostSignificantBits());
        bb.putLong(originalUUID.getLeastSignificantBits());

        BasicDBObject find = new BasicDBObject("_id", bb.array()); //Also tried flipping bb.

None of these things worked. Can someone provide some insight into this, with a solution?

Thank you!

like image 322
Sasanka Panguluri Avatar asked Mar 04 '26 08:03

Sasanka Panguluri


1 Answers

You're very close. The only reason it's not working is that the query matcher also matches on the subtype of the binary. Try this instead:

    UUID originalUUID = UUID.fromString("7ee973c0-54b5-11e4-aaed-0002a5d5c51b");
    MongoClient mongoClient = new MongoClient();
    DB db = mongoClient.getDB("test");
    DBCollection coll = db.getCollection("test");

    BasicDBObject query = new BasicDBObject("_id", originalUUID);
    coll.save(query);

    byte[] bytes = new byte[16];
    ByteBuffer bb = ByteBuffer.wrap(bytes);
    bb.order(ByteOrder.LITTLE_ENDIAN);

    bb.putLong(originalUUID.getMostSignificantBits());
    bb.putLong(originalUUID.getLeastSignificantBits());

    System.out.println(coll.findOne(originalUUID));
    System.out.println(coll.findOne(new Binary(Bytes.B_UUID, bb.array())));  // note use of the B_UUID subtype

It should print:

    { "_id" : { "$uuid" : "7ee973c0-54b5-11e4-aaed-0002a5d5c51b"}}
    { "_id" : { "$uuid" : "7ee973c0-54b5-11e4-aaed-0002a5d5c51b"}}
like image 151
jyemin Avatar answered Mar 06 '26 21:03

jyemin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!