Динамически нажимать, тянуть и устанавливать на обновление схемы мангуста - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь настроить свой патч api, чтобы я мог создать динамический запрос для отправки, извлечения и установки данных в моей схеме mongoose.У меня есть множество значений, которые я бы изменил, используя 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}, нормально:0, errmsg: 'Обновление пути \' status \ 'приведет к конфликту в \' status \ '', код: 40, codeName: 'ConflictingUpdateOperators', '$ clusterTime': {clusterTime: Timestamp { bsontype:«Метка времени», низкая : 1, высокая_: 1560978288}, подпись: {хэш: [Объект], идентификатор ключа: [Объект]}},

1 Ответ

0 голосов
/ 20 июня 2019

О, вы делаете этот $ 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 };
// ...

Таким образом, ваши запросы никак не конфликтуют.

...