Mongoose预查找OneAndUpdate挂钩问题

mspsb9vt  于 2022-11-13  发布在  Go
关注(0)|答案(7)|浏览(173)

我正在尝试更新pre钩子的计数。问题是由于一些未知的原因,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对象。
我遗漏了什么?* 如何使用pre钩子更新findOneAndUpdate上的计数?*

iyzzxitl

iyzzxitl1#

你可以这样做-〉

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

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

pgvzfuti

pgvzfuti2#

该文件规定:
查询中间件与文档中间件有一个细微但重要的区别:在文档中间件中,this指的是要更新的文档,在查询中间件中,mongoose不一定有要更新的文档的引用,所以this指的是query对象,而不是要更新的文档。
一个更新动作通常更新一个只存在于数据库中的文档(它告诉MongoDB服务器:* “查找文档X并将属性X设置为值Z”*),因此Mongoose无法使用完整的文档,因此,您无法更新计数(这至少需要访问您要确定其长度的数组)。
顺便说一句:为什么在模式中需要单独的*Count属性呢?如果要查询与特定大小匹配的数组,可以直接在数组上使用$size操作符。
如果确实需要count属性,那么对于每次更新,都需要跟踪对每个数组所做的更改的数量(根据添加/删除的项数),并使用$inc操作符来调整计数。

lstz6jyr

lstz6jyr3#

我在使用updateOne方法时遇到了类似的问题,我还打算在保存到数据库之前使用updateOne pre钩子进行间歇性更新。我找不到一种方法来使它工作。我最终使用了findOneAndUpdate pre钩子并在其中执行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()
})
wyyhbhjk

wyyhbhjk4#

另一个解决方案是使用中间件上的官方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();   
     });
crcmnpdw

crcmnpdw5#

这对我很有效

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

tnkciper6#

schema.pre(['findOneAndUpdate'], async function(next) {
        try {
            const type = this.get('type')
            const query = this.getQuery()

            const doc =  await this.findOne(query)

            if (type) {
                this.set('type', doc.type)
            }

            next()
        } catch (e) {
            next(new BaseError(e))
        }
    })
unhi4e5o

unhi4e5o7#

mongoose文档:

  • 您无法在pre('updateOne ')或pre('findOneAndUpdate')查询中间件中访问正在更新的文档。如果需要访问将被更新的文档,则需要对该文档执行显式查询。*
schema.pre('findOneAndUpdate', async function() {
  const docToUpdate = await this.model.findOne(this.getQuery());
  console.log(docToUpdate); // The document that `findOneAndUpdate()` will modify
});

相关问题