猫鼬:更新文档并使用中间件

时间:2018-07-11 22:47:33

标签: node.js express mongoose

在某些情况下,我使用猫鼬.pre('save')钩子将某些数据非规范化为其他文档。我正在努力寻找一种很好的解决方案来更新数据并在整个数据库中保持非规范化的一致性。如果要更新文档,可以考虑以下三种选择:

  1. 执行原子更新

我不愿意这样做的原因是,它不会触发我需要对数据进行非规范化的猫鼬中间件。

  1. 使用.post('update')钩子

此方法的问题在于我无法在挂钩中告诉哪些字段已更新,对吗?因此,我应该假设所有字段都已更新并且对整个数据库中的数据进行非规范化处理?似乎非常激烈。

  1. 获取文档,对其进行修改然后保存

这似乎很方便,但是存在重写数据的风险,即是否要在“中间”时刻从其他位置更新文档。

in models / car.model.js:

const { mongoose } = require('mongoose');
const Schema = mongoose.Schema;

const Manufacturer = require('./manufacturer.model.js');

const CarSchema = new Schema({
    name: String,
    manufacturer: {
        type: {
            _id: Schema.Types.ObjectId,
            name: String,
        },
    },
});

CarSchema.pre('save', async function(next) {
    /*
    if (this.isModified('name')) {
        await Manufacturer.findByIdAndUpdate(this.manufacturer, {
            $set: {
                car-name: this.name,
            },
        });
    }
    */
    if (this.isModified('manufacturer') {
        const manufacturer = await Manufacturer.findOne({
            _id: this.manufacturer._id,
        }, {
            name: 1,
        });
        this.manufacturer.name = manufacturer.name;
    }
});

controllers / car.controller.js:

app.patch('/:id', async function (req, res, next) {
    const car = await Car.findById(req.params.id);
    // Bad solution, helps please
    for (var key in req.body) {
        car[key] = req.body[key];
    }
    await car.save();
    res.sendStatus(200);
});

有什么解决方案可以同时兼顾两个方面?

1 个答案:

答案 0 :(得分:1)

数字2是一个可行的选择,您只需在post('update')钩中使用https://activemq.apache.org/artemis/docs/latest/configuration-index.html即可this.getUpdate()。另外,执行原子更新(例如updateOne())有什么问题?

此外,很高兴看到您正在使用异步中间件,但是仅供参考,您不需要context: 'query'