在实例方法中执行$ inc,获取更新的文档 [英] Perform $inc in instance method, get updated document

查看:58
本文介绍了在实例方法中执行$ inc,获取更新的文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Mongoose中有一个实例方法,我需要在一个字段上执行Mongo的$inc运算符.我的理解是,从v3开始,Mongoose不支持除更新方法以外的任何形式的$inc(例如,没有Mongoose方法可以获取Mongoose文档对象的字段并对其执行$inc,然后在避免比赛条件的方式)

I have an instance method in Mongoose where I need to perform Mongo's $inc operator on a field. My understanding is that since v3, Mongoose does not support $inc in any form other than an update method (e.g. there's no Mongoose method to take a Mongoose document object's field and perform $inc on it, then call save in a way that would avoid race conditions)

回调函数需要一个更新的用户对象,其中反映了更新更改.但是,以这种方式进行更新不会更新正在执行实例方法的原始文档.余额和购买字段保持不变.

The callback function needs an updated user object with the update changes reflected. However, updating in this way does not update the original document from which we are performing the instance method. It's balance and purchases fields remain untouched.

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,该模型将返回更新的文档.然后,让调用方法来处理返回的更新后的用户对象.

As an alternate, I've tried to call findByIdAndUpdate on the model itself, which returns the updated document. Then I leave it up to the calling method to do something useful with the returned updated user object.

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

但是这样做会导致以下错误

But doing this results in the following error

project/node_modules/mongoose/node_modules/mquery/lib/utils.js:26
if (/ObjectI[dD]$/.test(obj.constructor.name)) {
                   ^
RangeError: Maximum call stack size exceeded

在Mongoose实例方法中执行$inc$addToSet调用(使更新的文档可访问)的正确方法是什么?

What is the proper way to perform an $inc or $addToSet call within a Mongoose instance method that will make the updated document accessible?

推荐答案

这似乎是您要寻找的机器人:

This would seem like the droids you are looking for:

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

    $inc:
      balance: incBalance
  , cb

或使用JavaScript:

Or in 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,对不起!)来呼叫:

And you would call as (JavaScript, sorry!):

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

或者至少对我有用.

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

});

这篇关于在实例方法中执行$ inc,获取更新的文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆