Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create unique autoincrement field with mongoose [duplicate]

Given a Schema:

var EventSchema = new Schema({
    id: {
        // ...
    },
    name: {
        type: String
    },
});

I want to make id unique and autoincrement. I try to realize mongodb implementation but have problems of understanding how to do it right in mongoose.

My question is: what is the right way to implement autoincrement field in mongoose without using any plugins and so on?

like image 636
Glen Swift Avatar asked Apr 21 '14 14:04

Glen Swift


2 Answers

const ModelIncrementSchema = new Schema({
    model: { type: String, required: true, index: { unique: true } },
    idx: { type: Number, default: 0 }
});

ModelIncrementSchema.statics.getNextId = async function(modelName, callback) {
    let incr = await this.findOne({ model: modelName });

    if (!incr) incr = await new this({ model: modelName }).save();
    incr.idx++;
    incr.save();
    return incr.idx;
};


const PageSchema = new Schema({
    id: { type: Number ,  default: 0},
    title: { type: String },
    description: { type: String }
});


PageSchema.pre('save', async function(next) {
    if (this.isNew) {
        const id = await ModelIncrement.getNextId('Page');
        this.id = id; // Incremented
        next();
    } else {
        next();
    }
});
like image 121
Natali Avatar answered Oct 22 '22 18:10

Natali


Yes, here's the "skinny" on that feature.

You need to have that collection in your mongo database. It acts as concurrent key allocation single record of truth if you want. Mongo's example shows you how to perform an "atomic" operation to get the next key and ensure that even there are concurrent requests you will be guaranteed to have the unique key returned without collisions.

But, mongodb doesn't implement that mechanism natively, they show you how to do it. They only provide for the _id to be used as unique document key. I hope this clarifies your approach.

To expand on the idea, go ahead and add that mongo suggested implementation to your defined Mongoose model and as you already guessed, use it in Pre-save or better yet pre-init event to ensure you always generate an id if you work with a collection server side before you save it to mongo.

like image 1
Biba Avatar answered Oct 22 '22 19:10

Biba