当我使用Model.findOneAndUpdate时,不会调用用于保存和更新的猫鼬预钩



我用猫鼬创建了一个快速应用程序。我还创建了一个保存和更新钩子,如下所示:

userSchema.pre("update", async function save(next) {
console.log("inside update")
});
userSchema.pre("update", async function save(next) {
console.log("inside save")
});

但是每当我调用一个Model.findOneAndUpdate()没有调用预钩子时,saveupdate预钩对findOneAndUpdate不起作用吗?

如猫鼬文档中所述,Pre 和 post save(( 钩子不会在 update(( 和 findOneAndUpdate(( 上执行。

为此,您需要使用findOneAndUpdate钩子。但是您无法访问将使用此关键字更新的文档。 如果需要访问将要更新的文档,则需要对文档执行显式查询。

userSchema.pre("findOneAndUpdate", async function() {
console.log("I am working");
const docToUpdate = await this.model.findOne(this.getQuery());
console.log(docToUpdate); // The document that `findOneAndUpdate()` will modify
});

或者,如果您可以使用如下this.set()设置字段值:

userSchema.pre("findOneAndUpdate", async function() {
console.log("I am working");
this.set({ updatedAt: new Date() });
});

假设我们有这样的用户架构:

const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: String,
updatedAt: {
type: Date,
default: Date.now
}
});
userSchema.pre("findOneAndUpdate", async function() {
console.log("I am working");
this.set({ updatedAt: new Date() });
});
module.exports = mongoose.model("User", userSchema);

而这个用户文档:

{
"updatedAt": "2020-01-30T19:48:46.207Z",
"_id": "5e33332ba7c5ee3b98ec6efb",
"name": "User 1",
"__v": 0
}

当我们像这样更新此用户名时:

router.put("/users/:id", async (req, res) => {
let result = await User.findOneAndUpdate(
{ _id: req.params.id },
{ name: req.body.name },
{ new: true }
);
res.send(result);
});

updatedAt字段值将设置为用户,并将对其进行更新。

您可以将save(( 函数与 findOne(( 一起使用:

const newName = 'whatever';
const user = await User.findOne({id});
user.name = newName;
user.save();

这将调用pre hook,但您需要注意在预保存函数中更改的路径

最新更新