node.js - MongooseJS 在预 Hook 期间修改文档

标签 node.js mongodb express mongoose compoundjs

我在使用 mongoose 时遇到了一些问题。我的目标是在预保存期间,我将能够修改对象,在需要时执行诸如拆分标签之类的操作,或者在另一种情况下计算子文档持续时间的总和并在主文档中更新它。

我发现如果我加载一个模型,然后调用 doc.update 传递新数据,只有 schema.pre('update', ...) 触发器,以及任何我的中间件中对 this 的更改未更新。我还尝试在我的更新中间件中使用 this.set('...', ....); 但无济于事。

似乎如果我改为执行 doc.save(...),然后在 schema.pre('save', .. .) 按预期附加。除了将发布的变量扩展到我的模型的属性中并保存之外,我没有看到任何利用 doc.update 来达到此目的的方法。

我的目标: - 通过 doc.update(properties, ....) 更新现有文档 - 保存时使用中间件修改文档,做高级验证,更新相关文档 - 更新时使用中间件修改文档,做高级验证,更新相关文档 - 可互换使用 model.findByIdAndUpdate、model.save、model.findById->doc.update、model.findById->doc.save 并全部接入我的保存/更新中间件。

一些任意示例代码:

function loadLocation(c) {
    var self = this;
    c.Location.findById(c.params.id, function(err, location) {
        c.respondTo(function(format) {
            if (err | !location) {
                format.json(function() {
                    c.send(err ? {
                        code: 500,
                        error: err
                    } : {
                        code: 404,
                        error: 'Location Not Found!'
                    });
                });
                format.html(function() {
                    c.redirect(c.path_to.admin_locations);
                });
            } else {
                self.location = location;
                c.next();
            }
        });
    });
}

LocationController.prototype.update = function update(c) {
    var location = this.location;
    this.title = 'Edit Location Details';

    location.update(c.body.Location, function(err) {
        c.respondTo(function(format) {
            format.json(function() {
                c.send(err ? {
                    code: 500,
                    error: location && location.errors || err
                } : {
                    code: 200,
                    location: location.toObject()
                });
            });
            format.html(function() {
                if (err) {
                    c.flash('error', JSON.stringify(err));
                } else {
                    c.flash('info', 'Location updated');
                }
                c.redirect(c.path_to.admin_location(location.id));
            });
        });
    });
};

module.exports = function(compound) {
    var schema = mongoose.Schema({
        name: String,
        address: String,
        tags: [{ type: String, index: true }],
        geo: {
            type: {
                type: String,
            default:
                "Point"
            },
            coordinates: [Number] // Longitude, Latitude
        }
    });
    schema.index({
        geo: '2dsphere'
    });
    var Location = mongoose.model('Location', schema);
    Location.modelName = 'Location';
    compound.models.Location = Location;

    schema.pre('save', function(next) {
        if(typeof this.tags === 'string') {
            this.tags = this.tags.split(',');
        }
    });
};

==== * 修订样本 * ====

module.exports = function(compound) {
    var schema = mongoose.Schema({
        name: String,
        bio: String
    });

    schema.pre('save', function(next) {
        console.log('Saving...');
        this.bio = "Tristique sed magna tortor?"; 
        next();
    });

    schema.pre('update', function(next) {
        console.log('Updating...');
        this.bio = "Quis ac, aenean egestas?"; 
        next();
    });

    var Author = mongoose.model('Author', schema);
    Author.modelName = 'Author';
    compound.models.Location = Author;
};

最佳答案

pre Hook 适用于 doc.save()doc.update()。在这两种情况下,this 都指的是文档本身。

请注意,在编译模型之前需要将 Hook 添加到您的架构中。

schema.pre('save', function(next) {
    if(typeof this.tags === 'string') {
        this.tags = this.tags.split(',');
    }
});
var Location = mongoose.model('Location', schema);

关于node.js - MongooseJS 在预 Hook 期间修改文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18221473/

相关文章:

node.js - 表达静态文件服务配置

node.js - 如何在 res.render 函数中指定布局?

node.js - 我想使用 Alexa API 读取杂货 list (用于在网络应用程序中显示)。我必须写入 "skill"吗?

json - 按 id 从 Node.js 应用程序搜索嵌套 json

node.js - Nodejs 并不总是显示错误

mongodb - CarrierWave 将图像保存到 gridfs 并在后台 s3 上传

php - Nodejs 和 wamp 服务器混淆

mongodb - 使用 MongoDB 协议(protocol)对 Azure DocumentDb 进行部分更新支持

javascript - 使用 Passed Mongodb 通过 res.render ('jadeview' 快速检索数据,在 Jade View 中邮寄 :mongodbretriveddata) in script. 标签?

javascript - 对于 html 表单发布请求,formdata 对象为空