Mongoose是否支持Mongodb`searchAndModify`方法?

时间:2011-09-07 13:07:52

标签: mongodb mongoose

我想使用findAndModify使用Mongoose以原子方式递增字段。

但是,下面的代码会引发错误“TypeError:Object#have method'seadAndModify'”:

// defining schema for the "counters" table
var tableSchema = new Schema({
    _id: String,
    next: Number        
});

// creating table object for the counters table
var counters_table = mongoose.model('counters', tableSchema);
var tableObj = new counters_table();    

// increment the "next" field on the table object
var query = {_id: 'messagetransaction'};
var update = {'$inc': {next: 1}};
var ret = tableObj.findAndModify(query, [], update, true, true, function(err) {
     if (err) { 
         throw err;
     }
     else { 
         console.log("updated!");
     }
});

9 个答案:

答案 0 :(得分:61)

该功能记录不完整(阅读:完全记录),但在阅读完源代码后,我想出了以下解决方案。

创建您的收藏架构。

var Counters = new Schema({
  _id: String,
  next: Number     
});

在架构上创建一个静态方法,该方法将公开模型集合的findAndModify方法。

Counters.statics.findAndModify = function (query, sort, doc, options, callback) {
  return this.collection.findAndModify(query, sort, doc, options, callback);
};

创建模型。

var Counter = mongoose.model('counters', Counters);

查找并修改

Counter.findAndModify({ _id: 'messagetransaction' }, [], { $inc: { next: 1 } }, {}, function (err, counter) {
  if (err) throw err;
  console.log('updated, counter is ' + counter.next);
});

<强>加成

Counters.statics.increment = function (counter, callback) {
  return this.collection.findAndModify({ _id: counter }, [], { $inc: { next: 1 } }, callback);
};

Counter.increment('messagetransaction', callback);

答案 1 :(得分:18)

答案 2 :(得分:14)

为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);
};

使用类似的东西:

Counter.increment('photo', function (err, result) {
    if (err) {
        console.error('Counter on photo save error: ' + err); return;
    }
    photo.cid = result.next;
    photo.save();
});

我希望有人派上用场。

答案 3 :(得分:6)

在版本3中,mongoose findOneAndUpdate方法公开了mongodb的findAndModify操作。它的工作原理如下:

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);
});

此处有更多信息:http://aaronheckmann.tumblr.com/post/48943524629/mongoose-v3-part-2-findandmodify

答案 4 :(得分:3)

我将findAndModify改为

  • 升级计数器(如果不存在则创建并初始化)
  • 递增计数器
  • 使用递增值
  • 调用回调
使用以下代码在单个DB往返中

var Counters = new Schema({
  _id:String, // the schema name
  count: Number
});

Counters.statics.findAndModify = function (query, sort, doc, options, callback) {
    return this.collection.findAndModify(query, sort, doc, options, callback);
};

var Counter = mongoose.model('Counter', Counters);

/**
 * Increments the counter associated with the given schema name.
 * @param {string} schemaName The name of the schema for which to
 *   increment the associated counter.
 * @param {function(err, count)} The callback called with the updated
 *   count (a Number).
 */
function incrementCounter(schemaName, callback){
  Counter.findAndModify({ _id: schemaName }, [], 
    { $inc: { count: 1 } }, {"new":true, upsert:true}, function (err, result) {
      if (err)
        callback(err);
      else
        callback(null, result.count);
  });
}

享受! - Curran

答案 5 :(得分:3)

很多答案,但我找到了这个简单的解决方案。

Counter.findByIdAndUpdate(ID, {$inc: {next:1}}, function (err, data) {


});

答案 6 :(得分:1)

https://jsfiddle.net/Lpjxse6L/获取上述回复,这是我的promised解决方案:

// eslint-disable-next-line func-names
localeTypesSchema.statics.findAndModify = function (query, sort, update, opts, callback) {
    const cb = callback || (() => { });
    try {
        const result = this.collection.findAndModify(query || {}, sort || [], update || {}, opts);
        cb(null, result);
        return Promise.resolve(result);
    } catch (err) {
        cb(err);
        return Promise.reject(err);
    }
};

答案 7 :(得分:0)

我建议使用http://www.mongodb.org/display/DOCS/findAndModify+Command底部显示的直接命令样式。我对mongoose不太熟悉,不知道运行命令的方法,但所有驱动程序都提供了一些方法。如果mongoose没有,你可以使用http://www.mongodb.org/display/DOCS/Commands顶部描述的样式直接进行。

那就是说,你应该确保你真的需要findAndModify而且update不会做你需要它做的事情。要查看update能够查看http://www.mongodb.org/display/DOCS/Updating的内容。

答案 8 :(得分:0)

只是添加到furf回答如果你在查询中使用objectId,mongoDB将无法找到你的文档。猫鼬层负责将你从路由参数获得的十六进制字符串对象id转换为正确的对象id。

要解决此问题,您需要:

var ObjectID = require('mongodb').ObjectID;


var itemId = req.params.itemId;
var objectId = ObjectID.createFromHexString(itemId);
Item.findAndModify({_id: objectId},