Does Mongoose support the Mongodb `findAndModify` method?
The feature is not well (read: at all) documented, but after reading through the source code, I came up with the following solution.
Create your collection schema.
var Counters = new Schema({ _id: String, next: Number });
Create a static method on the schema which will expose the findAndModify method of the model's collection.
Counters.statics.findAndModify = function (query, sort, doc, options, callback) { return this.collection.findAndModify(query, sort, doc, options, callback);};
Create your model.
var Counter = mongoose.model('counters', Counters);
Find and modify!
Counter.findAndModify({ _id: 'messagetransaction' }, [], { $inc: { next: 1 } }, {}, function (err, counter) { if (err) throw err; console.log('updated, counter is ' + counter.next);});
Bonus
Counters.statics.increment = function (counter, callback) { return this.collection.findAndModify({ _id: counter }, [], { $inc: { next: 1 } }, callback);};Counter.increment('messagetransaction', callback);
This is fully supported in Mongoose 3.x now, though the name is slightly different.
http://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
http://mongoosejs.com/docs/api.html#model_Model.findByIdAndUpdate
http://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove
http://mongoosejs.com/docs/api.html#model_Model.findByIdAndRemove
Made working version increment for Mongoose 3.x
var mongoose = require('mongoose');var CounterSchema = new mongoose.Schema({ _id: String, next: {type: Number, default: 1}});CounterSchema.statics.increment = function (counter, callback) { return this.findByIdAndUpdate(counter, { $inc: { next: 1 } }, {new: true, upsert: true, select: {next: 1}}, callback);};
Use something like this:
Counter.increment('photo', function (err, result) { if (err) { console.error('Counter on photo save error: ' + err); return; } photo.cid = result.next; photo.save();});
I hope someone come in handy