Экспресс / Монго может выдвигать новые данные, но не может обновить существующие данные - PullRequest
0 голосов
/ 09 октября 2019

У меня есть бэкэнд Express / Mongo, и я пытаюсь обновить данные «вручную».

Я звоню UserObj.findById(req.params.id, function(err,doc){... callback ...})

И в функции обратного вызова я обновляю документ. Я могу push новые данные в результате запроса doc (а затем в базу данных Mongo), но если я попытаюсь обновить существующие данные в doc, в то время как в моем console.log это показывает, doc был обновлен, когда я смотрю в Mongo DB, данные фактически не обновлялись.

Это поведение по умолчанию в Mongo, или я где-то ошибаюсь? Если это поведение по умолчанию, что лучше обходить? Я стараюсь избегать использования встроенных функций findByIdAndUpdate, потому что надеюсь получить больше ручного контроля над тем, как я обрабатываю каждое поле. (Например, для определенных полей я хочу push новые данные, а для других полей я хочу update существующие данные).

Вот соответствующие части из обратного вызова контроллера (users_controller.user_details_update):

    exports.user_details_post = [(req, res, next)=> {
        //LOG, VALIDATE, SANITIZE
. . . 
. . .         
        //SAVE
        (req,res, next) =>{
            const errors = validationResult(req);

            if (!errors.isEmpty()) {
                // Handle Validation Errors
            } else {
                let user = UserObj.findById(req.params.id, function(err,doc){
                    let activeArr = [];
                    let maxActive = 0;

                    if (err) {}
                    Object.keys(doc["_doc"]).forEach(sec=>{
                       Object.keys(doc["_doc"][sec]["_doc"]).filter(fld=>doc["_doc"][sec]["_doc"][fld].hasOwnProperty("value")).forEach(fld=> {
                         activeArr = [];
                         maxActive = +doc["_doc"][sec]["_doc"][fld]["attr"]["active"].reduce((acc,cur)=>Math.max(acc, cur),-Infinity);
                         Object.keys(req.body).filter(reqFld=>
                                        new RegExp(`^${fld}__${sec}--[0-9]*-[0-9]*`).test(reqFld)).forEach(reqFld=> {
                           let activeVal = +reqFld.split(SEC_SPLIT_CHAR)[1].split(ROW_SPLIT_CHAR)[1];
                           if (activeVal > maxActive) {
                             doc["_doc"][sec]["_doc"][fld]["value"].push(req.body[reqFld])  // THIS    
                                                                                           // WORKS FINE
                           } else if (activeVal===maxActive) {
                             doc["_doc"][sec]["_doc"][fld]["value"][0]=req.body[reqFld]  // NO ERRORS 
                                                                              // THROWN, BUT THE 
                                                                              // DOCUMENT DOESN'T GET 
                                                                              // UPDATED IN MONGODB
 . . . 
 . . .                    
                   // SAVE
                    doc.save(function(err){  // SAVE WORKS OK. NO ERRORS
                        if (err) { return next(err);}
                    });
                    console.log("redirecting . . . ")
                    res.redirect("http://localhost:4200/");  // EXITS NORMALLY
                });
            }
        },
    ];

Кроме того, когда я проверяю объект doc в обратном вызове, я вижу, что он содержит некоторые «добавленные» поля ["_doc"] в двух верхних уровнях иерархии объектов. Могут ли мои проблемы иметь какое-либо отношение к тому, как я справляюсь с этими «дополнительными» полями? Или я застрял с необходимостью создать совершенно новый пользовательский объект, записать обновленные данные в этот объект, а затем скопировать _id из старого объекта? (Кажется несколько расточительным, чтобы сделать это таким образом).

Спасибо!

==========

Мне пока не удалось найти другой способ, кроме копирования обновленного doc в новый UserObj, удалите старый UserObj, а затем переключите _id нового пользователя на _id старого пользователя, как показано ниже:


. . . 
. . . 

                    thisUser = doc;

                });
                user.remove().then(result=>{
                    sameUser = new UserObj(thisUser);
                    sameUser._id = thisUser._id;
                },err=>next(err)).then(result=>{
                    sameUser.save(err=>{
                        console.log("Saving DETAILS . . . ")
                        if (err) { return next(err);}
                        console.log("Saved DETAILS . . . Now redirecting ");
                        res.redirect("http://localhost:4200/");

                    })
                })

Лично, пока онработает, я нахожу это решение слегка грязным и несколько не элегантным. Если кто-нибудь сможет найти лучшее решение, я буду очень признателен и выберу это в качестве ответа. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...