Ze Jibe
Ze Jibe

Reputation: 1043

How to automatically generate custom id's in Mongoose?

I'd like to manage my own _id's through Mongoose/MongoDB - as the default ones are pretty long and consume bandwidth.

The difficulty is that I need to create them (say, by incrementing a counter), but I need to do this in a concurrent environment (Node.JS). Is there a simple example I could follow that creates a schema, with a custom _id and a static method (or anything better) that automatically generates the next unique _id, whenever a new document is created?

Upvotes: 2

Views: 5936

Answers (3)

Binh Ho
Binh Ho

Reputation: 4993

This should work

import { randomString } from '@/helpers'

const taskSchema = new mongoose.Schema({
    _id: {
        type: String,
        unique: true,
        default: randomString
    },
    title: String,
    ...
})

Random string function

// helpers

export const randomString = (length?: number) => {
    let result = ''
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    const charactersLength = characters.length
    const n = length || 15
    for (let i = 0; i < n; i++) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength))
    }

    return result
}

Tested result

{ "_id": "EIa9W2J5mY2lMDY", ... }

Upvotes: 2

Hector Correa
Hector Correa

Reputation: 26700

You could use Mongo's findAndModify() to generate sequential values. Below is an example of this:

// (assuming db is a reference to a MongoDB database)
var counters = db.collection('counters');
var query = {'name': 'counterName'};
var order = [['_id','asc']];
var inc = {$inc:{'next':1}};
var options = {new: true, upsert: true};
counters.findAndModify(query, order, inc, options, function(err, doc) {

  if(err) {
    callback(err);
    return;
  }      

  var id = doc.next;
  callback(null, id);
});

Although generating sequential IDs looks pretty on applications keep in mind that there are some drawbacks to them (e.g. when you need to split your database geographically) which is why Mongo uses the long pseudo-random keys that it does.

Upvotes: 3

Nick Mitchinson
Nick Mitchinson

Reputation: 5480

As Chad briefly touched on, Mongo implements a uuid system for you, taking into account the timestamp, network address, and machine name, plus an autoincrementing 2 digit counter (in the event that multiple entries with the same timestamp occur). This schema is used to allow distributed databases (ie, running different database instances on different machines) while ensuring that each entry will still have a unique identifier (because the machine name section will be different).

Trying to role out your own schema would likely greatly limit the scalability that mongo provides.

Upvotes: 3

Related Questions