猫鼬使用预存中间件推送到数组

Mongoose pushing to an Array using presave middleware

我正在尝试使用 mongoose 中可用的预保存挂钩更新数组。我将此数组用于审计目的,因此我想使用这些中间件强制执行正确的值

这是我的架构

const taskSchema = new mongoose.Schema({
id: { type: String, required: true },
status: { type: String, required: true },
code: { type: String, required: true }, // ENQUIRY
events:{
    type:[{
            status: {type: String, required: true},
            date:{ type: Date, required: true}

    }], required: false
},
assignedTo: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: false },
}, {timestamps:true});

保存中间件挂钩的逻辑非常有效。

taskSchema.pre('save', async function(next) {
    try {
        let event = {}
        let now = Date.now();
        event.status = this.status;
        event.date = now;
        this.events.push(event);
        next();
    } catch (error) {
        console.log(error);
        next(error);
    }
});

在 findOneAndUpdate 挂钩中使用时出错

taskSchema.pre('findOneAndUpdate', async function(next) {
    try {

        let event={}
        let now = Date.now();
        event.status = this._update.status;
        event.date = now;
        this.events.push(event);
        next();
    } catch (error) {
        console.log(error);
        next(error);
    }
});

我不确定我在这里遗漏了什么。这是错误

TypeError: Cannot read property 'push' of undefined 

我看到 this.events 未定义。

如何访问该数组以更新它?我也应该忽略 request.body.events

中发送的任何内容

提前致谢。

参考Types of Middleware, save is document middleware and findOneAndUpdate is query middleware. And in notes,它说:

Query middleware differs from document middleware in a subtle but important way: in document middleware, this refers to the document being updated. In query middleware, mongoose doesn't necessarily have a reference to the document being updated, so this refers to the query object rather than the document being updated.

所以在你的 findOneAndUpdate 之前,this.eventsundefined

对于您的情况,使用以下代码可能会解决问题:

taskSchema.pre('findOneAndUpdate', async function(next) {
  try {

    let event={}
    let now = Date.now();
    event.status = this._update.status;
    event.date = now;
    this._update['$push'] = {events: event};
    next();
  } catch (error) {
    console.log(error);
    next(error);
  }
});