ObjectId to long and back

3,791 views
Skip to first unread message

Octavian Covalschi

unread,
Aug 8, 2011, 11:35:06 PM8/8/11
to mongod...@googlegroups.com
Hi there,

I'm trying to implement a simple recommendation engine using Mahout. I'm using MongoDB to store all information and of course all my _ids are of ObjectId type... The problem is that Mahout is looking for longs for userId and itemId in order to make it's magic....

So, I'm looking a simple way to convert ObjectId to long and back. A way In order to keep uniqueness of course. So far I've come up with a solution, but it involves saving inc part of the id. Basically in order to restore an ObjectId from a long, I need to save long value and inc part...


    static long objectIdToLong(ObjectId id) {
        ByteBuffer bb = ByteBuffer.wrap(id.toByteArray())
        return bb.getLong().longValue()
    }

    static ObjectId longToObjectId(long l, int inc) {
        byte[] b  = new byte[12]
        ByteBuffer bb2 = ByteBuffer.wrap(b);
        bb2.putLong(l);
        bb2.putInt(inc);
        return new ObjectId(b)
    }

This is doing what I need, but I'm not sure if it's the right way to do it...

Thanks.

Scott Hernandez

unread,
Aug 8, 2011, 11:38:32 PM8/8/11
to mongod...@googlegroups.com
What about just using longs for the _id values? You don't need to use
the default ObjectId for the _id field.

> --
> You received this message because you are subscribed to the Google Groups
> "mongodb-user" group.
> To post to this group, send email to mongod...@googlegroups.com.
> To unsubscribe from this group, send email to
> mongodb-user...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/mongodb-user?hl=en.
>

Octavian Covalschi

unread,
Aug 8, 2011, 11:51:06 PM8/8/11
to mongod...@googlegroups.com
Yes, I know, but I thought it's recommended to use ObjectId and the app is already in production...

Also, since I'm using Grails framework, not sure how well will it work  with long instead of ObjectId, its MongoDB plugin is still in a beta like mode... and don't want to mess to much with it...

Thanks!

Octavian Covalschi

unread,
Aug 11, 2011, 11:27:01 AM8/11/11
to mongod...@googlegroups.com
OK, looks like i'll have to have additional column for long id or an additional collection with ObjectId <-> long mapping... for specific tasks... basically when I'll generate mahout's input file, I'll generate long numbers and save them to that collection...

The code I have posted before it's not working as I expect, basically the long number that comes out of 

Thanks.

Octavian Covalschi

unread,
Aug 11, 2011, 11:32:34 AM8/11/11
to mongod...@googlegroups.com
Sorry did not finish my thought...

For some reason this piece of code, will generate the same long number for different ObjectId(yes, they are different) in my case I have 7 collisions... 

 ByteBuffer.wrap(id.toByteArray()).getLong().longValue()

Thanks again.

Scott Hernandez

unread,
Aug 11, 2011, 11:37:34 AM8/11/11
to mongod...@googlegroups.com
Well yes, an ObjectId is 12 bytes and a long is 8 bytes so you will
have collisions when reducing the amount of bits being used.

On Thu, Aug 11, 2011 at 11:32 AM, Octavian Covalschi

Gergely Nagy

unread,
Aug 11, 2011, 11:39:13 AM8/11/11
to mongod...@googlegroups.com
On Thu, Aug 11, 2011 at 17:32, Octavian Covalschi
<octavian....@gmail.com> wrote:
> Sorry did not finish my thought...
> For some reason this piece of code, will generate the same long number for
> different ObjectId(yes, they are different) in my case I have 7
> collisions...

That's because an ObjectId is longer than a 64-bit long. While an
ObjectId is 96 bits (or 12 bytes), a 64bit long is well, 64 bits only.
So you have 32 bits that are truncated. It's no wonder you get
collisions.

--
|8]

Octavian Covalschi

unread,
Aug 11, 2011, 11:42:21 AM8/11/11
to mongod...@googlegroups.com
I see, it makes sense now.  It's been a while since I worked with bits and paid attention to bytes..

Thanks for you time.

Samita Mahajan

unread,
Jun 15, 2016, 9:09:54 AM6/15/16
to mongodb-user, octavian....@gmail.com
 static long objectIdToLong(ObjectId id) {
        ByteBuffer bb = ByteBuffer.wrap(id.toByteArray());
        return bb.getLong();
    }

    static ObjectId longToObjectId(long l, int inc) {
   
        byte[] b  = new byte[12];
        ByteBuffer bb2 = ByteBuffer.wrap(b);
        bb2.putLong(l);
        bb2.putInt(inc);
        return new ObjectId(b);
    }

public static void main(String[] args) {
ObjectId tt = new ObjectId("575feb0adaf8e8f1fa424746");
long value = objectIdToLong(tt);
System.out.println(value);
ObjectId id = longToObjectId(value , 32);
System.out.println(id);
}

It  shows wrong result 

My object id : 575feb0adaf8e8f1fa424746
Converting Long value : 6296009235943188721
Result object id : 575feb0adaf8e8f100000020

Reply all
Reply to author
Forward
0 new messages