initialize = function (connection) { try { IdentityCounter = connection.model('IdentityCounter'); } catch (ex) { if (ex.name === 'MissingSchemaError') { // Create new counter schema. counterSchema = new mongoose.Schema({ model: { type: String, require: true }, field: { type: String, require: true }, count: { type: Number, default: 0 } }); // Create a unique index using the "field" and "model" fields. counterSchema.index({ field: 1, model: 1 }, { unique: true, required: true, index: -1 }); // Create model using new schema. IdentityCounter = connection.model('IdentityCounter', counterSchema); } else throw ex; } }
...
````js
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
autoIncrement = require('mongoose-auto-increment');
var connection = mongoose.createConnection("mongodb://localhost/myDatabase");
autoIncrement.initialize(connection);
var bookSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});
...
plugin = function (schema, options) { // If we don't have reference to the counterSchema or the IdentityCounter model then the plugin was most likely not // initialized properly so throw an error. if (!counterSchema || !IdentityCounter) throw new Error("mongoose-auto-increment has not been initialized"); // Default settings and plugin scope variables. var settings = { model: null, // The model to configure the plugin for. field: '_id', // The field the plugin should track. startAt: 0, // The number the count should start at. incrementBy: 1, // The number by which to increment the count each time. unique: true // Should we create a unique index for the field }, fields = {}, // A hash of fields to add properties to in Mongoose. ready = false; // True if the counter collection has been updated and the document is ready to be saved. switch (typeof(options)) { // If string, the user chose to pass in just the model name. case 'string': settings.model = options; break; // If object, the user passed in a hash of options. case 'object': extend(settings, options); break; } if (settings.model == null) throw new Error("model must be set"); // Add properties for field in schema. fields[settings.field] = { type: Number, require: true }; if (settings.field !== '_id') fields[settings.field].unique = settings.unique schema.add(fields); // Find the counter for this model and the relevant field. IdentityCounter.findOne( { model: settings.model, field: settings.field }, function (err, counter) { if (!counter) { // If no counter exists then create one and save it. counter = new IdentityCounter({ model: settings.model, field: settings.field, count: settings.startAt - settings.incrementBy }); counter.save(function () { ready = true; }); } else { ready = true; } } ); // Declare a function to get the next counter for the model/schema. var nextCount = function (callback) { IdentityCounter.findOne({ model: settings.model, field: settings.field }, function (err, counter) { if (err) return callback(err); callback(null, counter === null ? settings.startAt : counter.count + settings.incrementBy); }); }; // Add nextCount as both a method on documents and a static on the schema for convenience. schema.method('nextCount', nextCount); schema.static('nextCount', nextCount); // Declare a function to reset counter at the start value - increment value. var resetCount = function (callback) { IdentityCounter.findOneAndUpdate( { model: settings.model, field: settings.field }, { count: settings.startAt - settings.incrementBy }, { new: true }, // new: true specifies that the callback should get the updated counter. function (err) { if (err) return callback(err); callback(null, settings.startAt); } ); }; // Add resetCount as both a method on documents and a static on the schema for convenience. schema.method('resetCount', resetCount); schema.static('resetCount', resetCount); // Every time documents in this schema are saved, run this logic. schema.pre('save', function (next) { // Get reference to the document being saved. var doc = this; // Only do this if it is a new document (see http://mongoosejs.com/docs/api.html#document_Document-isNew) if (doc.isNew) { // Declare self-invoking save function. (function save() { // If ready, run increment logic. // Note: ready is true when an existing counter collection is found or after it is created for the // first time. if (ready) { // check that a number has already been provided, and update the counter to that number if it is // greater than the current count if (typeof doc[settings.field] === 'number') { IdentityCounter.findOneAndUpdate( // IdentityCounter documents are identified by the model and ...
...
var bookSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});
bookSchema.plugin(autoIncrement.plugin, 'Book');
var Book = connection.model('Book', bookSchema);
````
That's it. Now you can create book entities at will and they will have an `_id` field added of type `Number` and will automatically
increment with each new document. Even declaring references is easy, just remember to change the reference property's type
to `Number` instead of `ObjectId` if the referenced model is also using the plugin.
````js
var authorSchema = new mongoose.Schema({
...
initialize = function (connection) { try { IdentityCounter = connection.model('IdentityCounter'); } catch (ex) { if (ex.name === 'MissingSchemaError') { // Create new counter schema. counterSchema = new mongoose.Schema({ model: { type: String, require: true }, field: { type: String, require: true }, count: { type: Number, default: 0 } }); // Create a unique index using the "field" and "model" fields. counterSchema.index({ field: 1, model: 1 }, { unique: true, required: true, index: -1 }); // Create model using new schema. IdentityCounter = connection.model('IdentityCounter', counterSchema); } else throw ex; } }
...
````js
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
autoIncrement = require('mongoose-auto-increment');
var connection = mongoose.createConnection("mongodb://localhost/myDatabase");
autoIncrement.initialize(connection);
var bookSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});
...
plugin = function (schema, options) { // If we don't have reference to the counterSchema or the IdentityCounter model then the plugin was most likely not // initialized properly so throw an error. if (!counterSchema || !IdentityCounter) throw new Error("mongoose-auto-increment has not been initialized"); // Default settings and plugin scope variables. var settings = { model: null, // The model to configure the plugin for. field: '_id', // The field the plugin should track. startAt: 0, // The number the count should start at. incrementBy: 1, // The number by which to increment the count each time. unique: true // Should we create a unique index for the field }, fields = {}, // A hash of fields to add properties to in Mongoose. ready = false; // True if the counter collection has been updated and the document is ready to be saved. switch (typeof(options)) { // If string, the user chose to pass in just the model name. case 'string': settings.model = options; break; // If object, the user passed in a hash of options. case 'object': extend(settings, options); break; } if (settings.model == null) throw new Error("model must be set"); // Add properties for field in schema. fields[settings.field] = { type: Number, require: true }; if (settings.field !== '_id') fields[settings.field].unique = settings.unique schema.add(fields); // Find the counter for this model and the relevant field. IdentityCounter.findOne( { model: settings.model, field: settings.field }, function (err, counter) { if (!counter) { // If no counter exists then create one and save it. counter = new IdentityCounter({ model: settings.model, field: settings.field, count: settings.startAt - settings.incrementBy }); counter.save(function () { ready = true; }); } else { ready = true; } } ); // Declare a function to get the next counter for the model/schema. var nextCount = function (callback) { IdentityCounter.findOne({ model: settings.model, field: settings.field }, function (err, counter) { if (err) return callback(err); callback(null, counter === null ? settings.startAt : counter.count + settings.incrementBy); }); }; // Add nextCount as both a method on documents and a static on the schema for convenience. schema.method('nextCount', nextCount); schema.static('nextCount', nextCount); // Declare a function to reset counter at the start value - increment value. var resetCount = function (callback) { IdentityCounter.findOneAndUpdate( { model: settings.model, field: settings.field }, { count: settings.startAt - settings.incrementBy }, { new: true }, // new: true specifies that the callback should get the updated counter. function (err) { if (err) return callback(err); callback(null, settings.startAt); } ); }; // Add resetCount as both a method on documents and a static on the schema for convenience. schema.method('resetCount', resetCount); schema.static('resetCount', resetCount); // Every time documents in this schema are saved, run this logic. schema.pre('save', function (next) { // Get reference to the document being saved. var doc = this; // Only do this if it is a new document (see http://mongoosejs.com/docs/api.html#document_Document-isNew) if (doc.isNew) { // Declare self-invoking save function. (function save() { // If ready, run increment logic. // Note: ready is true when an existing counter collection is found or after it is created for the // first time. if (ready) { // check that a number has already been provided, and update the counter to that number if it is // greater than the current count if (typeof doc[settings.field] === 'number') { IdentityCounter.findOneAndUpdate( // IdentityCounter documents are identified by the model and ...
...
var bookSchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});
bookSchema.plugin(autoIncrement.plugin, 'Book');
var Book = connection.model('Book', bookSchema);
````
That's it. Now you can create book entities at will and they will have an `_id` field added of type `Number` and will automatically
increment with each new document. Even declaring references is easy, just remember to change the reference property's type
to `Number` instead of `ObjectId` if the referenced model is also using the plugin.
````js
var authorSchema = new mongoose.Schema({
...