Mongoose.js:isModified标志为具有默认值的属性
我有一个默认生成值的模型,在整个文档生命周期中不会改变,除非在特殊情况下。
使用doc.update({_id: doc._id, deleted_at: new Date()}, {overwrite: true})
将文档标记为已删除
在一个非常特殊的情况下,这个文件可能会被“复活” – 被它的id抬起头,然后再被使用。
在保存前钩子中,每当文档被创build或复活时,我都需要执行一些操作(例如将文档存储在另一个集合中)。
考虑下面的简化代码:
'use strict'; var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/test'); var someSchema = mongoose.Schema({ immutable: { type: String, default: function () { return 'SomeVeryRandomValue'; } } }); someSchema.pre('save', function (next) { if (this.isNew || this.isModified('immutable')) { console.log('Processing pre-save hook!'); } next(); }); var SomeModel = mongoose.model('SomeModel', someSchema, 'test'); mongoose.connection.once('open', function (err) { var testDoc = new SomeModel({}); console.log('New: %j', testDoc.toObject()); testDoc.save(function(err) { console.log('Initial saved: %j', testDoc.toObject()); testDoc.update({_id: testDoc._id}, {overwrite: true}, function (err) { // at this point using mongo console: // > db.test.findOne() // { "_id" : ObjectId("5617b028bf84f0a93687cf67") } SomeModel.findById(testDoc.id, function(err, reloadedDoc) { console.log('Reloaded: %j', reloadedDoc.toObject()); console.log('reloaded isModified(\'immutable\'): %j', reloadedDoc.isModified('immutable')); reloadedDoc.save(function(err) { console.log('Re-saved: %j', reloadedDoc); mongoose.connection.close(); }); }); }); }); });
脚本运行时输出:
$ node mongoose-modified-test.js New: {"_id":"5617b64c5376737b46f6bb98","immutable":"SomeVeryRandomValue"} Processing pre-save hook! Initial saved: {"__v":0,"_id":"5617b64c5376737b46f6bb98","immutable":"SomeVeryRandomValue"} Reloaded: {"_id":"5617b64c5376737b46f6bb98","immutable":"SomeVeryRandomValue"} reloaded isModified('immutable'): false Re-saved: {"_id":"5617b64c5376737b46f6bb98","immutable":"SomeVeryRandomValue"}
immutable
的不被标记为修改,恕我直言,它应该 – 原始文件没有该属性的值。
解决方法是删除immutable
属性的默认值,并像这样定义预validation钩子:
someSchema.pre('validate', function (next) { if (this.isNew || !this.immutable) { this.immutable = 'SomeVeryRandomValue'; } next(); });
这不是我所需要的,因为在我尝试validation/保存文档之前,不会生成这个值。 new SomeModel({})
上不执行前/后的挂钩,所以我不能使用这些。
我应该为mongoose.js打开一个问题吗?
this.$isDefault('immutable')
可以用来代替。
someSchema.pre('save', function (next) { if (this.isNew || this.$isDefault('immutable')) { console.log('Processing pre-save hook!'); } next(); });
使用更新的预保存钩子输出脚本:
$ node --harmony mongoose-modified-test.js New: {"_id":"56276f0c1a2f17ae7e0a03f7","immutable":"SomeVeryRandomValue"} Processing pre-save hook! Initial saved: {"__v":0,"_id":"56276f0c1a2f17ae7e0a03f7","immutable":"SomeVeryRandomValue"} Reloaded: {"_id":"56276f0c1a2f17ae7e0a03f7","immutable":"SomeVeryRandomValue"} Processing pre-save hook! Re-saved: {"_id":"56276f0c1a2f17ae7e0a03f7","immutable":"SomeVeryRandomValue"}
感谢@ vkarpov15 澄清 。