【发布时间】:2019-02-21 01:16:11
【问题描述】:
我在我的 MongoDB/Node 后端使用 pre 和 post 钩子来比较文档的预保存和保存后版本,以便我可以根据更改的内容通过模型触发器生成注释。在我的一个模型/集合中,这是有效的,但在另一个模型/集合中,它没有按预期工作,我不知道为什么。
在问题案例中,一些研究已经确定,即使我在使用 save() 的操作上调用 pre 钩子触发器,但当我控制台输出在该 pre 钩子中传递的文档状态时,它是已经应用了更改。换句话说,据我所知,钩子不是在save() 操作之前触发,而是在之后触发。
这是我的相关型号代码:
let Schema = mongoose
.Schema(CustomerSchema, {
timestamps: true
})
.pre("save", function(next) {
const doc = this;
console.log("doc in .pre: ", doc); // this should be the pre-save version of the doc, but it is the post-save version
console.log("doc.history.length in model doc: ", doc.history.length);
trigger.preSave(doc);
next();
})
.post("save", function(doc) {
trigger.postSave(doc);
})
.post("update", function(doc) {
trigger.postSave(doc);
});
module.exports = mongoose.model("Customer", Schema);
我正在执行的save() 操作的相关部分如下所示(我所做的只是将一个新元素推送到文档中名为“history”的数组):
exports.updateHistory = async function(req, res) {
let request = new CentralReqController(
req,
res,
{
// Allowed Parameters
id: {
type: String
},
stageId: {
type: String
},
startedBy: {
type: String
}
},
[
// Required Parameters
"id",
"stageId",
"startedBy"
]
);
let newHistoryObj = {
stageId: request.parameters.stageId,
startDate: new Date(),
startedBy: request.parameters.startedBy,
completed: false
};
let customerToUpdate = await Customer.findOne({
_id: request.parameters.id
}).exec();
let historyArray = await customerToUpdate.history;
console.log("historyArray.length before push in update func: ", historyArray.length);
historyArray.push(newHistoryObj);
await customerToUpdate.save((err, doc) => {
if (doc) console.log("history update saved...");
if (err) return request.sendError("Customer history update failed.", err);
});
};
所以,我的问题是,如果 save() 操作上的 pre 钩子应该在 save() 发生之前触发,为什么我通过 console.log 查看的文档会显示已经拥有的文档对save()做了操作吗?
【问题讨论】: