1

我正在尝试使用猫鼬中可用的 presave 钩子更新数组。我将此数组用于审计目的,因此我想使用这些中间件强制执行正确的值

这是我的架构

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 中发送的任何内容

提前致谢。

4

1 回答 1

2

参考中间件的类型文档中间件查询中间件。在notes中,它说:savefindOneAndUpdate

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

所以在你的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);
  }
});
于 2019-08-05T09:19:22.540 回答