首页 > 解决方案 > 当数据结构与 Mongoose 中的模型完全匹配时,如何一次增加多个字段?

问题描述

我目前有一个包含许多字段的模式,所有类型的编号都是这样的:

const mySchema = new mongoose.Schema({
    fields: {
        field1: {
            type: Number,
            default: 0
        },
        field2: {
            type: Number,
            default: 0
        },
        ...
        field20: {
            type: Number,
            default: 0
        }
    }
});

const MyModel = mongoose.model('model', mySchema);
module.exports = MyModel;

我目前单独增加所有字段:

const fields = {
    field1: 5,
    field2: 10,
    ...
    field20: 7
};

MyModel.findOneAndUpdate(
    {...},
    {
        $inc: {
            "fields.field1": fields.field1,
            "fields.field2": fields.field2,
            ...
            "fields.field20": fields.field20
        }
    }
);

有没有一种简单的方法可以一次增加所有这些字段?如下所示:

MyModel.findOneAndUpdate(
    {...},
    {
        $inc: {
            "fields": fields
        }
    }
);

这可以理解地给出了错误

“不能使用非数字参数递增:...”

标签: javascriptmongodbmongoose

解决方案


mongodb ref 不支持您尝试执行的操作:https ://docs.mongodb.com/manual/reference/operator/update/inc/

但是,可以编写一个生成这些映射的辅助函数。

function generateIncrement(fields){
    return Object.keys(fields).reduce((mappings, key) => {
        mappings[`fields.${key}`] = fields[key]
        return mappings
    },{})
}

这会给

const fields = {
    field1: 5,
    field2: 10,
    ...
    field20: 7
};

MyModel.findOneAndUpdate(
    {...},
    {
        $inc: generateIncrement(fields)
    }
);

它也可以在模型中隔离

该模型将是

const mySchema = new mongoose.Schema({
    fields: {
        field1: {
            type: Number,
            default: 0
        },
        field2: {
            type: Number,
            default: 0
        },
        ...
        field20: {
            type: Number,
            default: 0
        }
    }
});
MyModel.static({
    incrementAllFields: async function incrementAllFields(query, fields) {
        return this.findOneAndUpdate(
            query,
            {
                $inc: generateIncrement(fields)
            }
        );
    }
})
const MyModel = mongoose.model('model', mySchema);
module.exports = MyModel;

用法会变成

const fields = {
    field1: 5,
    field2: 10,
    ...
    field20: 7
};

MyModel.incrementAllFields({...}, fields)

最后,还可以使辅助函数更通用以指定“根”键或支持深度路径安全搜索


推荐阅读