Node.js Mongoose.pre(';save';)不会触发

Node.js Mongoose.pre(';save';)不会触发,node.js,mongodb,express,mongoose,Node.js,Mongodb,Express,Mongoose,我为猫鼬提供了以下模型。model('quotes'): 对于mongoose.model('settings'),还有一个额外的模式,用于存储递增唯一索引Quote.number的递增编号。在每次保存之前,调用quoteschema.pre('save')读取、增加nextQuoteNumber并将其作为this.number传递给相应的next()函数 但是,在其他地方保存报价时,整个.pre('save')功能似乎不会触发。Mongoose中止保存,因为number是必需的,但没有定义,而

我为猫鼬提供了以下模型。
model('quotes')

对于
mongoose.model('settings')
,还有一个额外的模式,用于存储递增唯一索引
Quote.number
的递增编号。在每次保存之前,调用
quoteschema.pre('save')
读取、增加
nextQuoteNumber
并将其作为
this.number
传递给相应的
next()
函数

但是,在其他地方保存
报价时,整个
.pre('save')
功能似乎不会触发。Mongoose中止保存,因为
number
是必需的,但没有定义,而且没有
console.log()
i写入函数时会输出任何内容。

使用
pre('validate')
而不是
pre('save')
来设置所需字段的值。Mongoose在保存文档之前对文档进行验证,因此,如果存在验证错误,则不会调用
save
中间件。将中间件从
save
切换到
validate
将使您的函数在验证之前设置数字字段

quotesSchema.pre('validate', true, function(next) {
  Setting.findByIdAndUpdate(currentSettingsId, { $inc: { nextQuoteNumber: 1 } }, function (err, settings) {
    if (err) { console.log(err) };
    this.number = settings.nextQuoteNumber - 1; // substract 1 because I need the 'current' sequence number, not the next
    next();
  });
});

我遇到了一个pre('validate')没有帮助的情况,因此我使用了pre('save')。我了解到一些操作直接在数据库上执行,因此不会调用mongoose中间件。我更改了将触发.pre('save')的路由端点。我使用Lodash对主体进行解析,只更新传递给服务器的字段

router.post("/", async function(req, res, next){
    try{
        const body = req.body;
        const doc  = await MyModel.findById(body._id);
        _.forEach(body, function(value, key) {
            doc[key] = value;
        });

        doc.save().then( doc => {
            res.status(200);
            res.send(doc);
            res.end();
        });

    }catch (err) {
        res.status(500);
        res.send({error: err.message});
        res.end();
    }

});

在某些情况下,我们可以使用

UserSchema.pre<User>(/^(updateOne|save|findOneAndUpdate)/, function (next) {
UserSchema.pre(/^(updateOne | save | findOneAndUpdate)/,函数(下一步){
但我在函数中使用“this”来获取数据,而不使用findOneAndUpdate触发器

我需要使用

  async update (id: string, doc: Partial<UserProps>): Promise<User | null> {
    const result = await this.userModel.findById(id)
    Object.assign(result, doc)
    await result?.save()
    return result
  }
异步更新(id:string,doc:Partial):承诺{ const result=wait this.userModel.findById(id) 分配对象(结果、单据) 等待结果?.save() 返回结果 }
而不是

  async update (id: string, doc: Partial<UserProps>): Promise<User | null> {
    const result = await this.userModel.findByIdAndUpdate(id, doc, { new: true, useFindAndModify: false })
    return result
  }
异步更新(id:string,doc:Partial):承诺{ const result=wait this.userModel.findByIdAndUpdate(id,doc,{new:true,useFindAndModify:false}) 返回结果 }
对于被谷歌重定向到这里的人,请确保在
方法和hooks声明之后调用
mongoose.model()

谢谢。我最后只是在
pre('save')中做了这个动作
无论何时实际保存,因为它不会经常发生。我认为如果我没有在我的
编号
上设置
required:true
,我的变体也会工作?非常感谢!我有一个
required
唯一的
字段没有初始化,尝试预保存挂钩也无法工作直到我像你说的那样切换到验证。
  async update (id: string, doc: Partial<UserProps>): Promise<User | null> {
    const result = await this.userModel.findByIdAndUpdate(id, doc, { new: true, useFindAndModify: false })
    return result
  }