Задать вопрос

Nodejs Mongoose update двух документов?

Доброго времени суток. Я недавно начал использовать Node Js и MongoDb. Допустим, есть стандартная система постов, пользователей и лайков к постам. Документ Post содержит поле favoriteCount, документ User содержит массив favorites, который содержит id лайкнутого поста. Нужно сделать так, чтобы после при лайке поста, id поста записывалось в массив документа User, а favoriteCount поле документа Post инкрементировалось или декрементировалось. Я написал код, приведённый ниже. Является ли это правильным подходом? Какие есть замечания/предложения?

exports.addFavorite = function(req, res) {
    var postId = req.body.id;
    if (req.user) {
        User.findOne({_id: req.user.id}, function(err, user) {
            if (err) {

            }
            if (user) {
                var found = false,
                    action = '';

                if (_.findWhere(user.favorites, {id: postId})) {
                    found = true;
                }

                if (found) {
                    user.favorites = _.filter(user.favorites, function(item) {
                        return item.id != postId; 
                    });
                } else {
                    user.favorites.push({id: postId});
                }

                var incrDecr = found ? -1 : 1;

                async.parallel([
                    function postUpdate(callback) {
                        Post.findOneAndUpdate({_id: postId}, {$inc: {favoriteCount: incrDecr}}, {}, function(err, post) {
                            if (err) {
                                callback(err);
                                return;
                            }
                            if (post) {
                                callback(null, post);
                            }
                        });                     
                    },
                    function userUpdate(callback) {
                        user.save(function(err, user) {
                            if (err) {
                                callback(err);
                                return;
                            }
                            if (user) {
                                callback(null, user);
                            }
                        });
                    }
                ], function(err, results) {
                    return res.json({success: 1, action: (found ? 'remove' : 'add')});
                });
            }
        });
    }
}
  • Вопрос задан
  • 3009 просмотров
Подписаться 4 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
undassa
@undassa
Last.Backend
По порядку:
var postId = req.body.id; - body может равняться null - тогда приложение упадёт. Необходима проверка.

if (req.user) - не совсем корректная проверка, так как далее вы делаете запрос по вложенному полю id, которого может и не быть. А если его нет, то и нет смысла нагружать приложение лишним запросом в БД.

if(req.user && req.user.id) - более грамотный вариант.

Далее: всё верно, одним запросом конечно обновить 2 документа в разных коллекциях нельзя. Но я в вашем случае не вижу смысла использовать библиотеку async. Гораздо более идеологически правильным вариантом освоить событийное программирование. И просто вызывать последовательность событий при выполнении алгоритма.

var error = function (err) {
   //
}
event.on('error', error);

// где то там в глубине кода
if(err)  return event.emit('error', err);
event.emit('user save') // в случае отсутсвия ошибок


Могу более подробно прокомментировать если надо :)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы