node.js - 如何在保存后将属性保存到 Mongoose 文档

标签 node.js mongodb express mongoose mean

我正在使用 Mongoose 的 timestamps 架构选项在用户架构上创建 createdAtupdatedAt 属性(将它们称为“applicants”) 。我需要这个的唯一原因是弄清楚用户完成注册过程需要多长时间。当他们单击“让我们开始吧”按钮时,它会在后端创建用户并设置 createdAtupdatedAt 属性(此时,它们是相等的)。然后,当他们完成注册过程时,我想向数据库发送另一个调用并强制再次保存文档,从而更新 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/

相关文章:

node.js - 为 Vue 应用程序前端和 Node.js 后端配置 nginx

mongodb - 在 mongodb 中加入类似查询

javascript - 响应对象的 JSON 对象到 api 端点

node.js - 如何在 Mongoose 中进行聚合 + 填充

node.js - 使用 Node 的 http.get 函数获取 ECONNRESET 响应

node.js - Yeoman webapp 生成器与 sass 错误

node.js - node和nodejs的区别

node.js - 如何使用 MongoDB/mongoose 有效地获取帖子的评论?

mongodb - 什么是 mongodb 中的意向共享锁和意向排他锁?

node.js - Mongoose 嵌套文档