【问题标题】:Dynamically push, pull, and set on mongoose schema update动态推送、拉取和设置猫鼬模式更新
【发布时间】:2019-11-02 16:16:36
【问题描述】:

我正在尝试设置我的补丁 api,以便我可以创建一个动态查询来推送、拉取和设置我的猫鼬模式中的数据。我有很多可以使用 set 更改的值,但我也有一个对象数组,当我需要插入时需要调用 push,当我需要删除项目时需要调用它们。我正在尝试找到将其组合成动态结构的最佳方法。

架构:

const StepSchema = new Schema({
    position: {
        type: Number,
        required: true
    },
    name: {
        type: String,
        required: true
    },

    due_date: {
        type: Date
    },
    status: [{
        label: {
            type: String,
            enum: ['Inactive', 'In Progress', 'Flagged', 'Complete'],
            default: 'Inactive'
        },
        user: {
            type: Schema.Types.ObjectId,
            ref: 'users',
        },
        date: {
            type: Date
        }
    }],
    comments: [{
        user: {
            type: Schema.Types.ObjectId,
            ref: 'users',
            required: true
        },
        body: {
            type: String,
            required: true
        },
        date: {
            type: Date,
            required: true
        },
    }],

});

API:

router.patch('/',
    async (req, res) => {

    let setQuery = req.body;
    let pushQuery = {};
    let pullQuery = {};

    //remove id from set query
    delete setQuery.id;

    //if there is a comment
    if(req.body.comment){
        pushQuery.comments = req.body.comment
    }

    //if I need to remove a comment
    if(req.body.remove_comment){
        pullQuery.comments = {_id: req.body.remove_comment.id}
    }


    //Push new status into array
    if(req.body.status) {
        pushQuery.status = {
            label: req.body.status,
            user: req.user._id,
            date: new Date()
        };

        delete setQuery.status;
    }

    //update step
    await Step.findByIdAndUpdate(req.body.id, {$set: setQuery, $push: pushQuery, $pull: pushQuery})
                .then(step => {
                        if(!step){
                            errors.noflow = "There was a problem updating the step";
                            return res.status(400).json(errors);
                        }
                        res.json(step)
                    })
                .catch(err => {
                    console.log(err);
                    res.status(404).json(err);
                });




});

我在尝试将新状态推送到我的文档时遇到以下错误:

operationTime: Timestamp { bsontype: 'Timestamp', low: 1, high_: 1560978288 }, ok: 0, errmsg: '更新路径 \'status\' 会 在 \'status\'' 处创建冲突,代码:40,代号: 'ConflictingUpdateOperators', '$clusterTime': { clusterTime: 时间戳 { bsontype: 'Timestamp', low: 1, high_: 1560978288 }, 签名:{哈希:[Object],keyId:[Object]}},

【问题讨论】:

    标签: javascript mongodb mongoose mongoose-schema


    【解决方案1】:

    哦,您正在对状态执行 $set 和 $push。您的 pushQuery 试图让 status 成为文档上的一个数组,而您的 setQuery 想要将其设置为实际正文上的任何内容(我猜是同一个对象。

    快速修复是将其从设置对象中删除:

    delete setQuery.status
    

    做到这一点的一种合理且稳定的方法是实际上只从 req.body 中获取您在每个阶段真正想要的东西。示例:

    const { position, name, dueDate, status, comment, remove_comment } = req.body;
    const setQuery = { position, name, dueDate };
    const pushQuery = { status, comments: comment };
    // ...
    

    这样您的查询就不会发生任何冲突。

    【讨论】:

    • 在我将状态添加到我的 pushQuery 后,我将立即删除 setQuery.status
    • 抱歉,我跳过了。
    猜你喜欢
    • 2022-12-22
    • 2019-12-05
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    相关资源
    最近更新 更多