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


In version 3, the mongoose findOneAndUpdate method exposes mongodb's findAndModify operation. It works like so:

var query = { name: 'Sprinkls' };
var update = { name: 'Sprinkles' };
var options = { new: false };
Cat.findOneAndUpdate(query, update, options, function (err, cat) {
  if (err) ..
  render('cat', cat);
});

More info here: http://aaronheckmann.tumblr.com/post/48943524629/mongoose-v3-part-2-findandmodify