Skip to content
Advertisement

Shorten ObjectId in node.js and mongoose

my URLs look like this at the moment:

http://www.sitename.com/watch?companyId=507f1f77bcf86cd799439011&employeeId=507f191e810c19729de860ea&someOtherId=.....

So, as you can see, it gets pretty long, pretty fast. I was thinking about shortening these ObjectIds. Idea is that I should add new field called “shortId” to every model in my database. So instead of having:

var CompanySchema = mongoose.Schema({
  /* _id will be added automatically by mongoose */
  name:         {type: String},
  address:      {type: String},
  directorName: {type: String}
});

we would have this:

var CompanySchema = mongoose.Schema({
  /* _id will be added automatically by mongoose */
  shortId:      {type: String}, /* WE SHOULD ADD THIS */
  name:         {type: String},
  address:      {type: String},
  directorName: {type: String},
});

I found a way to do it like this:

// Encode
var b64 = new Buffer('47cc67093475061e3d95369d', 'hex')
  .toString('base64')
  .replace('+','-')
  .replace('/','_')
;
// -> shortID is now: R8xnCTR1Bh49lTad

But I still think it could be shorter.

Also, I found this npm module: https://www.npmjs.com/package/short-mongo-id but I don’t see it’s being used too much so I can’t tell if it’s reliable.

Anyone has any suggestions?

Advertisement

Answer

I ended up doing it like this:

Install shortId module (https://www.npmjs.com/package/shortid) Now you need to somehow stick this shortId to your objects when they’re being saved in the database. I found the easiest way to do this is to append this functionality on the end of mongoose’s function called “save()” (or “saveAsync()” if you promisified your model). You can do it like this:

var saveRef = Company.save;
Company.save = function() {
  var args = Array.prototype.slice.call(arguments, 0);
  // Add shortId to this company
  args[0].shortId = shortId.generate();
  return saveRef.apply(this, args);
};

So you just basically at each Model.save() function append this functionality to add shortId. That’s that.

Edit: Also, I discovered that you can do it better and cleaner like this straight in Schema.

var shortId = require('shortid');
var CompanySchema = mongoose.Schema({
  /* _id will be added automatically by mongoose */
  shortId: {type: String, unique: true, default: shortId.generate}, /* WE SHOULD ADD THIS */
  name: {type: String},
  address: {type: String},
  directorName: {type: String}
});

EDIT : Now you can use the nanoid library which is much more performant and optimized. The documentation is also nice : https://github.com/ai/nanoid/

Advertisement