Mongoose.js:属性的isModified标志,默认值为

时间:2015-10-09 13:32:32

标签: node.js mongoose

我有一个默认生成值的模型,除了一个特殊情况外,它在整个文档生命周期内都没有变化。

使用doc.update({_id: doc._id, deleted_at: new Date()}, {overwrite: true})

可能会将文档标记为已删除

在一个非常特殊的情况下,文件可能会被复活" - 抬头看看它的身份,然后再与之合作。

在预保存挂钩中,我需要在创建或恢复文档时执行某些操作(例如,将文档存储在另一个集合中)。

请考虑使用简化代码:

'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属性的默认值,并定义像这样的预验证钩子:

someSchema.pre('validate', function (next) {
    if (this.isNew || !this.immutable) {
        this.immutable = 'SomeVeryRandomValue';
    }
    next();
});

这不是我需要的,因为在我尝试验证/保存文档之前不会生成该值。 pre / post-init挂钩不会在new SomeModel({})上执行,所以我无法使用它们。

我应该为mongoose.js打开问题吗?

1 个答案:

答案 0 :(得分:1)

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 for clarification