在实例方法中执行$ inc,获取更新文档

时间:2014-03-19 01:25:53

标签: javascript node.js mongodb mongoose

我在Mongoose中有一个实例方法,我需要在一个字段上执行Mongo的$inc运算符。我的理解是,自从v3以来,Mongoose不支持除{update}方法之外的任何形式的$inc(例如,没有Mongoose方法来获取Mongoose文档对象的字段并执行{{1在它上面,然后以避免竞争条件的方式调用$inc

回调函数需要更新的用户对象,并反映更新更改。但是,以这种方式更新不会更新我们正在执行实例方法的原始文档。它的平衡和购买领域保持不变。

save

作为替代方案,我尝试在模型本身上调用usersSchema.methods.completePurchase = function(item, incBalance, cb) { return this.update({ $addToSet: { "purchases": item }, $inc: { "balance": incBalance } }, function(err) { // I NEED THE UPDATED USER AT THIS POINT return cb(err); }); }; ,它会返回更新的文档。然后我将它留给调用方法来对返回的更新用户对象做一些有用的事情。

findByIdAndUpdate

但这样做会导致以下错误

usersSchema.methods.completePurchase = function(item, incBalance, cb) {
  var model;
  model = this.model(this.constructor.modelName);
  return model.findByIdAndUpdate(this._id, {
    $addToSet: {
      "purchases": item
    },
    $inc: {
      "balance": incBalance
    }
  }, function(err, updatedUser) {
    // CRASHES BEFORE REACHING THIS POINT
    return cb(err, updatedUser);
  });
};

在Mongoose实例方法中执行project/node_modules/mongoose/node_modules/mquery/lib/utils.js:26 if (/ObjectI[dD]$/.test(obj.constructor.name)) { ^ RangeError: Maximum call stack size exceeded $inc调用的正确方法是什么,以便更新文档可访问?

1 个答案:

答案 0 :(得分:1)

这看起来像你正在寻找的机器人:

usersSchema.methods.completePurchase = (item, incBalance, cb) ->
  model = @model(@constructor.modelName, @schema)
  model.findByIdAndUpdate @_id,
    $addToSet:
      purchases: item

    $inc:
      balance: incBalance
  , cb

或者在JavaScript中:

usersSchema.methods.completePurchase = function(item, incBalance, cb) {

  var model = this.model(this.constructor.modelName, this.schema);
  return model.findByIdAndUpdate(this._id, {
    $addToSet: {
      purchases: item
    },
    $inc: {
      balance: incBalance
    }
  },
  cb);
};

你会打电话给(JavaScript,对不起!):

user.completePurchase(item, incBalance function(err,doc) {
    // Something here
})

或者至少那对我有用。


MyTest的


var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/nodetest')

var childSchema = new Schema({ name: 'string' });

var parentSchema = new Schema({
  children: [childSchema]
});

parentSchema.methods.findMe = function(cb) {
  return this.model(this.constructor.modelName, this.schema)
    .findById(this._id, cb);
};

var Parent = mongoose.model('Parent', parentSchema);

var parent = new Parent( { children: [{ name: 'Bart' }] });

parent.save(function(err,doc) {

  console.log( "saved: " + doc );
  doc.findMe(function(err,doc2) {
    console.log( "found: " + doc2 );
  });

});