我正在使用 Mongoose 的 timestamps
架构选项在用户架构上创建 createdAt
和 updatedAt
属性(将它们称为“applicants”) 。我需要这个的唯一原因是弄清楚用户完成注册过程需要多长时间。当他们单击“让我们开始吧”按钮时,它会在后端创建用户并设置 createdAt
和 updatedAt
属性(此时,它们是相等的)。然后,当他们完成注册过程时,我想向数据库发送另一个调用并强制再次保存文档,从而更新 updatedAt 属性。一旦发生这种情况,我想找到两个时间戳属性之间的时间差,看看它们完成该过程需要多长时间,然后将该值保存到 timeTaken
属性中。
问题是,我看到执行此操作的唯一方法是触发保存,然后在返回的 promise 中,在运行“保存后” Hook 以更新申请人的文档后再次保存文档。
代码可能更有意义:
申请人的架构
var applicantSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
lowercase: true
},
timeTaken: String
}, {timestamps: true});
applicantSchema.post("save", function () {
this.setTimeTaken();
});
applicantSchema.methods.setTimeTaken = function () {
var applicant = this;
var ms = this.updatedAt - this.createdAt;
var x = ms / 1000;
var seconds = Math.floor(x % 60);
x /= 60;
var minutes = Math.floor(x % 60);
x /= 60;
var hours = Math.floor(x % 24);
applicant.timeTaken = hours + "h:" + minutes + "m:" + seconds + "s";
};
申请路由器
applicantRouter.put("/:applicantId", function (req, res) {
Applicant.findById(req.params.applicantId, function (err, applicant) {
applicant.save().then(function () {
applicant.save(function (err, applicant) {
//console.log(applicant.timeTaken);
if (err) {
res.status(500).send(err)
} else {
res.send({success: true, timeTaken: applicant.timeTaken})
}
});
});
});
});
这是如何工作的:
PUT
请求到来,mongoose 在 mongodb 中搜索具有给定 id 的文档,然后触发“保存”事件。它由架构的“post save” Hook 捕获,该 Hook 调用文档的 setTimeTaken
方法。此方法更新文档上的属性,但由于这种情况发生在保存后,因此我需要再次保存它以使其持续存在。
我无法使用预保存 Hook ,因为它还没有更新 updatedAt
属性。
上面的代码确实有效,但我有点讨厌自己这样写。我感觉自己就像一个广告片 Actor :“一定有更好的方法!”
或者也许没有?有人更了解这个东西吗? 提前致谢
最佳答案
离开计算机几个小时后,我意识到我增加了太多的复杂性,并且太努力地尝试使用内置的时间戳选项。我刚刚更改了数学以包含 Date.now() - this.createdAt
,将 post save
更改为 pre save
,然后摆脱了额外的applicant.save()
:
申请人的架构:
var applicantSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
lowercase: true
},
timeTaken: String
}, {timestamps: true});
applicantSchema.pre("save", function (next) {
this.setTimeTaken();
next();
});
applicantSchema.methods.setTimeTaken = function () {
var applicant = this;
var ms = Date.now() - this.createdAt;
var x = ms / 1000;
var seconds = Math.floor(x % 60);
x /= 60;
var minutes = Math.floor(x % 60);
x /= 60;
var hours = Math.floor(x % 24);
applicant.timeTaken = hours + "h:" + minutes + "m:" + seconds + "s";
};
申请路由器:
applicantRouter.put("/:applicantId", function (req, res) {
Applicant.findById(req.params.applicantId, function (err, applicant) {
applicant.save(function (err, applicant) {
if (err) {
res.status(500).send(err)
} else {
res.send({success: true, timeTaken: applicant.timeTaken})
}
});
});
});
就像魅力一样。
关于node.js - 如何在保存后将属性保存到 Mongoose 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35785611/