Mongoose pre findOneAndUpdate挂钩问题

时间:2015-08-05 05:04:27

标签: mongoose

我正在尝试更新预挂钩上的计数。问题是,由于某些未知原因,findOneAndUpdate挂钩无法访问该文档,据我所知。

我想这样做:

source.pre('findOneAndUpdate', function (next) {
  console.log('------------->>>>>> findOneAndUpdate: ');
  this.objects = this.objects || [];
  this.people = this.people || [];
  this.events = this.events || [];

  this.objectCount = this.objects.length;
  this.peopleCount = this.people.length;
  this.eventCount = this.events.length;

  next();
});

但由于某些原因,钩子中的this不是文档,它的Query对象似乎没用。

我错过了什么? 如何使用预挂钩更新findOneAndUpdate上的计数?

5 个答案:

答案 0 :(得分:12)

你可以做那样的smthng - >

source.pre('findOneAndUpdate', function (next) {
    console.log('------------->>>>>> findOneAndUpdate: ');
    this._update.$set.objects = [];
    this._update.$set.people = [];
    this._update.$set.events =  [];
    next();
});

注意_update。$ set因为在上下文中“this”将是一个查询。所以你可以轻松添加你想要的任何东西!

答案 1 :(得分:7)

documentation州:

  

查询中间件与文档中间件的区别在于微妙但重要的方式:在文档中间件中,this指的是正在更新的文档。在查询中间件中,mongoose不一定要引用正在更新的文档,因此this指的是查询对象而不是正在更新的文档。

更新操作通常会更新仅存在于数据库中的文档(它告诉MongoDB服务器:"查找文档X并将属性X设置为值Z" ),因此Mongoose无法使用完整的文档,因此您无法更新计数(至少需要访问您想要确定其长度的数组)。

顺便说一下:为什么在架构中需要单独的*Count属性?如果要查询匹配特定大小的数组,可以直接在数组上使用$size运算符。

如果确实需要计数属性,那么对于每次更新,您需要跟踪对每个阵列所做的更改次数(根据添加/删除的项目数)并使用{{3 }}运算符来调整计数。

答案 2 :(得分:0)

当我使用updateOne方法时也遇到了类似的问题,并且还打算使用updateOne预挂钩在保存到数据库之前进行间歇更新。找不到工作的方法。我最终使用了findOneAndUpdate预钩,并在其中执行了updateOne。

schema.pre('findOneAndUpdate', async function(next){ 
     const schema = this;
     const { newUpdate } = schema.getUpdate();
     const queryConditions = schema._condition

     if(newUpdate){
       //some mutation magic
       await schema.updateOne(queryConditions, {newUpdate:"modified data"}); 
       next()
     }
     next()
})

答案 3 :(得分:0)

另一种解决方案是使用中间件上的官方MongoDB文档。他们解释了为什么“ this”不引用文档本身。您可以尝试使用这种方式进行尝试:

   source.pre('findOneAndUpdate', async function(next) {
     const docToUpdate = await this.model.findOne(this.getFilter());
        //modify the appropriate objects
     docToUpdate.save(function(err) {
       if(!err) {
         console.log("Document Updated");
        }
     });
    console.log(docToUpdate); 
     // The document that `findOneAndUpdate()` will modify
       next();   
     });

答案 4 :(得分:0)

这对我有用

SCHEMA.pre('findOneAndUpdate', function(next){
   this._update.yourNestedElement
   next();
});