如何将属性保存到mongoose文档保存

时间:2016-03-04 00:09:33

标签: node.js mongodb express mongoose mean

我正在使用Mongoose的timestamps架构选项在用户架构上创建createdAtupdatedAt属性(称之为“申请者”)。我需要这个的唯一原因是弄清楚用户完成注册过程需要多长时间。当他们点击“让我们开始”按钮时,它会在后端创建用户并设置createdAtupdatedAt属性(此时,它们是相同的)。然后当他们完成注册过程时,我想再发一次调用db并强制文档再次保存,从而更新updatedAt属性。一旦发生这种情况,我想找到两个时间戳属性之间的时间差,以查看完成该过程所需的时间,然后将该值保存到timeTaken属性。

问题是,我看到这样做的唯一方法是触发保存,然后在返回的承诺中,在“post save”挂钩运行后再次保存文档以更新申请人的文档。

使用代码可能会更有意义:

申请人的架构

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的文档,然后触发“save”事件。它被模式的“post save”钩子捕获,它调用文档的setTimeTaken方法。此方法更新了文档的属性,但由于发生发布保存,我需要再次保存以使其保持不变。

我无法使用预保存挂钩,因为它尚未更新updatedAt属性。

上面的代码实际上有效,但我有点讨厌自己用这种方式编写代码。我觉得自己是一个电视购物者:“ 是一个更好的方式!”

或者可能没有?谁知道这个东西更好? 提前致谢

1 个答案:

答案 0 :(得分:1)

离开电脑几个小时后,我意识到我增加了太多的复杂性,并且太难以使用内置的timestamps选项。我刚刚将数学改为包含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})
            }
        });
    });
});

像魅力一样。