Mongoose预保存挂钩是射击,但不保存附加字段(不使用model.update)

我试图在我的模式中实现一个计数器来获取下一个问题编号。 我已经在Mongoose中实现了它钩子预保存钩子,并且一切看起来都很好…除了实际的“数字”字段没有更新。 我可以很容易地告诉挂钩是由什么被login到控制台发射,即使这个领域似乎分配。 但是,可惜的是,无论我尝试什么,“数字”字段都没有结果。

我已经看到了几个与Mongoose钩子有关的问题,但是他们似乎都和findOneAndUpdate或类似的东西有关,我没有使用它们。

这是我的完整模型的底部挂钩:

var mongoose = require('mongoose'); var Schema = mongoose.Schema; var Project = require('./projects.js'); var IssueSchema = new Schema({ title: {type: String, required: true, trim: true, index: true}, number: {type: Number}, description: {type: String, required: true}, vote_up: {type: Number, default: 0}, vote_down: {type: Number, default: 0}, comments: [new Schema({ _id: {type: Schema.ObjectId, ref: 'users'}, description : {type: String}, likes: {type: Number}, date: {type: Date} })], attachments: [], fields: [new Schema({ _id: {type: Schema.ObjectId, ref: 'fields'}, value : {type: String} })], project: {type: Schema.ObjectId, required: true, index: true, ref: 'projects'}, tags: {type: [Schema.ObjectId], required: false, default: ['56a2a0b1ea805d403f6d014b']}, isResolved: {type: Boolean, default: false}, created_by: {type: Schema.ObjectId, required: true, ref: 'users'}, updated_by: {type: Schema.ObjectId, required: false, ref: 'users'}, created_at: {type: Date, default: Date.now}, updated_at: {type: Date, default: Date.now} }); IssueSchema.pre('save', function(next){ var now = new Date(); this.updated_at = now; if(!this.created_at) { this.created_at = now; } next(); }) .pre('save', function(next) { Project.findOne({_id: this.project}).select('numberSeq').exec(function(err, doc) { if (err) { console.log(err); } console.log('pre-save hook firing'); this.number = doc.numberSeq; console.log(this.number); next(); }); }) .post('save', function(doc) { Project.update({_id: doc.project}, {$inc: {numberSeq: 1}}, function(err, result) { if (err) { console.log(err); } console.log('Updated next number in seq for ' + doc.project); }); }); module.exports = mongoose.model('issues', IssueSchema); 

而插入问题的路线(我猜这是不是问题的地方)

 app.post('/api/issue/create', function(req, res) { var issue = new Issues({ title: req.body.title, description: req.body.description, fields: req.body.fields, attachments: req.body.attachments, project: req.body.project, created_by: req.user || req.body.created_by, }); issue.save(function(err, result) { if (err) { return res.status(409).send({message: 'There was an error creating the issue: ' + err}); } if (!result.number) { console.log('number = :('); } console.log(result); res.send({message: 'New issue created', result: result}); }); }); 

从日志控制台的结果屏幕截图

这里你错过了this背景,

 .pre('save', function(next) { Project.findOne({_id: this.project}).select('numberSeq').exec(function(err, doc) { if (err) { console.log(err); } console.log('pre-save hook firing'); this.number = doc.numberSeq; console.log(this.number); next(); }); }) 

你在哪里说:

 this.number = doc.numberSeq; console.log(this.number); 

实际上指的是findOne查询的callback函数,因此您将以正确的console.log和插入的错误数据结束。

您可以记住预保存钩子的这个上下文,然后在callback中使用该上下文更新数字。 如下所示:

 .pre('save', function(next) { var tat=this; Project.findOne({_id: this.project}).select('numberSeq').exec(function(err, doc) { if (err) { console.log(err); } console.log('pre-save hook firing'); tat.number = doc.numberSeq; console.log(tat.number); next(); }); })