【问题标题】:mongoose update selected fields only or insert猫鼬只更新选定的字段或插入
【发布时间】:2019-09-14 03:40:55
【问题描述】:

标题可能听起来像 findOne$set,但不知何故,我并没有让它按我想要的方式工作。

首先,我有一个 Ticket 架构

const Ticket = new Schema(Object.assign({
    ticketNumber: { type: String, required: true },
    year: { type: Schema.Types.Mixed, default: [] },  // object

}, BaseSchema), { timestamps: true });

然后我有一个将数据写入数据库的函数。

我在下面的代码中也有一个模型数据

exports.writeToDB = async () => {
    const data = [
        {
            ticketNumber: 123456789,
            year: 2019,
            notes: 'hello there',
            more: 'there should be more fields here'
        },
        {
            ticketNumber: 987654321,
            year: 2020,
            notes: 'hello there again',
            more: 'there should be more fields here again'
        }
    ];

    data.forEach(d => {
        console.log(d, 'ddd');
        const { ticketNumber, year, ...contents } = d;
        const query = { ticketNumber };
        const update = {
            'year': { [year]: contents }
        };
        const options = { upsert: true };
        Ticket.updateOne(query, update, options, (err, doc) => {
            console.log(doc, 'docc');
        })
    })
};

在架构中,只有 ticketNumberyear 一切都很好,但我想做的是,年份可能会有所不同,ticketNumber 会保持不变。每次传入数据时,如果找到ticketNumber,则根据year,则update,如果未找到year,则改为insert

db 中的示例是

{
    ticketNumber: 123456789,
    year: {
        2019: {
            notes: 'hello there',
            more: 'there should be more fields here'
        }
    }
};

如果数据是在同一年 2019 传入的,那么它将更新 notesmore 字段以及其他字段,但如果数据是在不同年份传入的,例如 2020 那么什么是在 db 中应该看起来像...

{
    ticketNumber: 123456789,
    year: [
        2019: {
            notes: 'hello there',
            more: 'there should be more fields here'
        },
        2020: {
            notes: 'hello there',
            more: 'there should be more fields here'
        },
    ]
};

我试图将我的update 变量配置成这样的

const update = {
    $set: {'year': { [year]: contents }}
};


const update = {
    'year': $set{ [year]: contents }
};

但是它们都不起作用,第一个会覆盖整个对象(这是预期的)。第二个实际上什么都不做

关于我应该做什么的任何建议,或者我应该提供其他逻辑而不是使用像 $set 这样的东西?

提前感谢您的任何帮助和建议。

【问题讨论】:

    标签: javascript mongodb mongoose mongodb-query


    【解决方案1】:

    我检查了mongoose api,Model.update方法在documentation中有这个注释:

    所有不是原子操作名称的顶级键都被视为集合操作:

    示例

    var query = { name: 'borne' };
    Model.update(query, { name: 'jason bourne' }, options, callback);
    
    // is sent as
    Model.update(query, { $set: { name: 'jason bourne' }}, options, function(err, res));
    // if overwrite option is false. If overwrite is true, sent without the $set wrapper.
    

    也就是说,在猫鼬上使用Model.update 时,您不必手动指定$set,只需执行以下操作:

    const update = {
        [`year.${year}`]: contents
    };
    

    【讨论】:

    • 啊,太好了!非常感谢,不知道我们可以这样写。 PS我必须先使year.${year}成为一个变量,否则我会得到一个错误,只是这样制作一个obj。所以我不得不做这样的事情const k = `year.${year}`; const update = { [k]: contents };
    • @Dora 是的,我会解决的。
    猜你喜欢
    • 2021-04-17
    • 2021-12-10
    • 2022-11-28
    • 1970-01-01
    • 2017-02-10
    • 2018-08-26
    • 2016-02-17
    • 2021-03-10
    • 1970-01-01
    相关资源
    最近更新 更多