开发者

Creating short, unique object id's in MongoDB

I'm making an app similar to instagram using Rails/Mongoid. I want a unique ID that I can use in a开发者_JAVA百科 url like http://instagr.am/p/DJmU8/

What's the easiest way to do that? Can I derive such an ID from the default BSON ObjectID Mongo creates?


You may try to use first 4 bytes of ObjectID (they will represent timestamp).

But, to be 100% safe, it's better to produce really unique short id, by implementing a counter. You can use separate collection to maintain current value of your counter.

More details on mongo's ObjectID structure can be found here: http://www.mongodb.org/display/DOCS/Object+IDs

As an alternative you can convert convert hex string id representation to a representation based on 36 symbols (26 latin letters + 10 digits). It will obviously be shorter.

It seems, that there is a ruby library, that can do such conversions http://rubyworks.github.com/radix/


Why not use dylang/shortid?

Install using npm npmjs.com/package/shortid:

npm i shortid

Then require:

const shortid = require('shortid');

In mongoose schema:

    new Schema {
        _id: {
            type: String,
            default: shortid.generate
        }
    }

or just insert directly:

    users.insert({
        _id: shortid.generate()
        name: ...
        email: ...
        });


You could try Mongoid::Token

https://github.com/thetron/mongoid_token

From the docs:

This library is a quick and simple way to generate unique, random tokens for your mongoid documents, in the cases where you can't, or don't want to use slugs, or the default MongoDB IDs.

Mongoid::Token can help turn this:

http://myawesomewebapp.com/video/4dcfbb3c6a4f1d4c4a000012/edit

Into something more like this:

http://myawesomewebapp.com/video/83xQ3r/edit


@aav was mention that you can use first 4 bytes, but this value are in seconds and you can get even 10.000 or more insert per seconds. Other thing objectID is Uniq and you need check "when" you get error from duplicate value "Write Concerns"?

new Date().getTime() - is in milliseconds => 1557702577900 why not use last 4 bytes ? Timestamp in base62 is rqiJgPq

This code look interesting:

https://github.com/treygriffith/short-mongo-id/blob/master/lib/objectIdToShortId.js

Check also ObjectID timestamp parser:

https://steveridout.github.io/mongo-object-time/

Or you can execute ObjectId().toString() and base of this string create new by hashids [nodejs,php, andmanymore]

Maybe best options it to use 4-5 bytes from js timestamp and INC from bson then hash this value by hids

Creating short, unique object id's in MongoDB

var id = ObjectID('61e33b8467a45920f80eba52').toString();

console.log("id:", id);
console.log("timestamp:", parseInt(id.substring(0, 8),16).toString());
console.log("machineID:", parseInt(id.substring(8, 14),16) );
console.log("processID:", parseInt(id.substring(14, 18),16) );
console.log("counter:", parseInt(id.slice(-6),16) );

var ObjTimestamp = parseInt(ObjectID2.substring(0, 8),16).toString().slice(-5);
var Counter = parseInt(ObjectID2.slice(-6),16);
//https://github.com/base62/base62.js/
console.log('Final:',base62.encode(parseInt(Counter) + parseInt(ObjTimestamp)  )); 

Output:

vI7o
15V9L
5t4l

You can get collision if: more process are running, then consider add PID to unique and when you run multiple instance on different computer


Try gem https://github.com/jffjs/mongoid_auto_inc


The Hashids library is meant for generating IDs like this. Check it out here ☞ https://github.com/peterhellberg/hashids.rb

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜