我有mongoose.model('quotes')
的以下模型:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var quotesSchema = new Schema({
created: { type: String, default: moment().format() },
type: { type: Number, default: 0 },
number: { type: Number, required: true },
title: { type: String, required: true, trim: true},
background: { type: String, required: true },
points: { type: Number, default: 1 },
status: { type: Number, default: 0 },
owner: { type: String, default: "anon" }
});
var settingsSchema = new Schema({
nextQuoteNumber: { type: Number, default: 1 }
});
// Save Setting Model earlier to use it below
mongoose.model('settings', settingsSchema);
var Setting = mongoose.model('settings');
quotesSchema.pre('save', true, function(next) {
Setting.findByIdAndUpdate(currentSettingsId, { $inc: { nextQuoteNumber: 1 } }, function (err, settings) {
if (err) { console.log(err) };
this.number = settings.nextQuoteNumber - 1; // substract 1 because I need the 'current' sequence number, not the next
next();
});
});
mongoose.model('quotes', quotesSchema);
mongoose.model('settings')
还有一个额外的Schema来存储递增的唯一索引Quote.number
我想要建立的递增数字。在每次保存之前,系统会调用quotesSchema.pre('save')
来读取,增加nextQuoteNumber
this.number
next()
到.pre('save')
函数。
但是,在其他地方保存Quote
时似乎没有触发整个number
函数。 Mongoose中止了保存,因为console.log()
是必需的但没有定义,并且没有{{1}}我写入函数输出任何内容。
答案 0 :(得分:28)
使用pre('validate')
代替pre('save')
来设置必填字段的值。 Mongoose在保存之前验证文档,因此如果存在验证错误,则不会调用save
中间件。将中间件从save
切换到validate
将使您的函数在验证之前设置数字字段。
quotesSchema.pre('validate', true, function(next) {
Setting.findByIdAndUpdate(currentSettingsId, { $inc: { nextQuoteNumber: 1 } }, function (err, settings) {
if (err) { console.log(err) };
this.number = settings.nextQuoteNumber - 1; // substract 1 because I need the 'current' sequence number, not the next
next();
});
});
答案 1 :(得分:4)
对于被 Google 重定向到此处的人,请确保您在调用 mongoose.model()
AFTER methods
和 hooks 声明。
答案 2 :(得分:0)
我遇到了pre('validate')没有帮助的情况,因此我使用了pre('save')。我读到一些操作是直接在数据库上执行的,因此不会调用猫鼬中间件。我更改了路由端点,这将触发.pre('save')。我用Lodash解析了正文,仅更新了传递给服务器的字段。
router.post("/", async function(req, res, next){
try{
const body = req.body;
const doc = await MyModel.findById(body._id);
_.forEach(body, function(value, key) {
doc[key] = value;
});
doc.save().then( doc => {
res.status(200);
res.send(doc);
res.end();
});
}catch (err) {
res.status(500);
res.send({error: err.message});
res.end();
}
});