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({
...