我试图在MongoDB后端中使用Mongoose pre
和post
钩子,以便比较文档在保存前和保存后的状态,从而根据事件触发其他事件改变了。但是到目前为止,我仍然无法通过Mongoose pre
钩子获取文档。
根据docs“钩子对doc.save()和doc.update()都起作用。在两种情况下,这都指向文档本身...”。所以我这就是我尝试过的。首先,在我的模型/模式中,我有以下代码:
let Schema = mongoose
.Schema(CustomerSchema, {
timestamps: true
})
.pre("findOneAndUpdate", function(next) {
trigger.preSave(next);
})
// other hooks
}
...然后在我的触发器文件中,我有以下代码:
exports.preSave = function(next) {
console.log("this: ", this);
}
};
但这是记录到控制台的内容:
此:{preSave:[Function],postSave:[AsyncFunction]}
很明显,这没有用。这并没有注销我希望的文件。为什么this
不能像文档本身所示那样在这里显示文档本身?有没有一种方法可以使我使用pre
钩子来保存文档?如果没有,人们是否曾经使用另一种方法来实现这一目标?
答案 0 :(得分:2)
您无法在pre
挂钩中检索文档。
根据documentation pre
是查询中间件,而this
是指查询而不是要更新的文档。
答案 1 :(得分:2)
由于每种中间件功能中this
上下文的不同而引起混乱。在文档 pre
或post
中间件期间,您可以使用this
访问文档模型,但不能使用其他挂钩。
中间件功能有 3种,所有功能都有前阶段和后阶段。
在文档中间件功能中,this
是指文档(模型)。
init, validate, save, remove
在查询中间件功能中,this
是指查询。
count,find,findOne,findOneAndRemove,findOneAndUpdate,update
在聚合中间件中,this
指的是聚合对象。
aggregate
在这里https://mongoosejs.com/docs/middleware.html#types-of-middleware
进行了说明因此,您只能在pre("init"), pre("init"), pre("validate"), post("validate"), pre("save"), post("save"), pre("remove"), post("remove")
期间访问文档,而不能访问其他任何文件。
我已经看到一些例子,人们在其他中间件挂钩中进行更多查询,以再次找到模型,但这对我来说听起来很危险。
简短的答案似乎是,您需要将原始查询更改为面向文档,而不是查询或聚合样式。这似乎是一个奇怪的限制。
答案 2 :(得分:2)
根据文档,您预钩子无法使文档生效,但可以按如下方式获取查询
schema.pre('findOneAndUpdate', async function() {
const docToUpdate = await this.model.findOne(this.getQuery());
console.log(docToUpdate); // The document that findOneAndUpdate() will modify
});