findOneAndUpdate (mon goose) возвращает true для обновления вложенного документа в модели, но ничего не обновляется - PullRequest
1 голос
/ 13 марта 2020

Да, я знаю, что есть очень похожие другие вопросы, и я смотрел на них, но, к сожалению, я не смог найти решение. Итак, я пытаюсь обновить вложенный документ в модели mon goose с помощью метода «findOneAndUpdate», но хотя он и возвращает документ, он является оригинальным, а не обновленным.

Ниже модель:

var mongoose = require('mongoose');

var teamMemberModelSchema = new mongoose.Schema({
    "_id": mongoose.SchemaTypes.ObjectId,
    "email": {
        "type": String,
        "required": true,
        "min": 5,
        "max": 20
    },
    "name": {
        "type": String,
        "required": true,
        "min": 5,
        "max": 20
    },
    "role": {
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    },
    "twitter": {
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    },
    "facebook": {
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    },
    "linkedin": {
        "type": String,
        "required": true,
        "min": 20,
        "max": 50
    },
});

var teamModelSchema = new mongoose.Schema({
    "title": {
        "type": String,
        "required": true,
        "min": 5,
        "max": 20
    },
    "headline": {
        "type": String,
        "required": true,
        "min": 5,
        "max": 30
    },
    "description": {
        "type": String,
        "required": true,
        "min": 5,
        "max": 80
    },
    "members": [teamMemberModelSchema]
}, { collection: 'team' });

teamModelSchema.set('collection', 'team');
mongoose.model('team', teamModelSchema);

Я хочу обновить вложенный документ участника следующим фрагментом кода:

module.exports.teamMemberUpdate = function (req, res) {

    var email = req.body.email;
    var name = req.body.name;
    var role = req.body.role;
    var twitter = req.body.twitter;
    var facebook = req.body.facebook;
    var linkedin = req.body.linkedin;

    teamFunctions.findTeamMember(email)
        .then(data => {

            if (data.length === 0) {
                responseUtilities.sendJSON(res, false, { "message": teamMsg.teamMemberNotFound });
            }
            else {
                return data[0];
            }

        })
        .then(() => {

            const query = { "members.email": email };
            const options = { new: true };
            var update = {
                $set: {
                    email: email,
                    name: name,
                    role: role,
                    twitter: twitter,
                    facebook: facebook,
                    linkedin: linkedin
                }
            };

            TeamModel.findOneAndUpdate(query, update, options, function (err, result) {
                var message = teamMsg.teamMemberUpdatedSuccess;
                if (!result) {
                    message = teamMsg.teamMemberUpdatedError;
                }
                responseUtilities.sendJSON(res, err, { "message": message });
            });

        })
        .catch(err => {
            console.log(err.message);
            responseUtilities.sendJSON(res, err, { "message": err.message });
        });
}

Отображается значение «teamMemberUpdatedSuccess», но на самом деле исходный документ не обновляется.

Может кто-нибудь узнать, в чем проблема?

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Вы можете использовать позиционный оператор $ с точечной нотацией. Здесь - это документы для вашего сценария.

Вы можете использовать следующую функцию, чтобы обновить участника с указанным адресом электронной почты. Как видите, у нас есть только один доступ к БД. Нет необходимости использовать функцию teamFunctions.findTeamMember.

Я использовал некоторые современные javascript функции, такие как деструктуризация объекта и синтаксис async / await для чистого кода.

module.exports.teamMemberUpdate = async function(req, res) {
  const { email, name, role, twitter, facebook, linkedin } = req.body;

  const query = {
    "members.email": email
  };

  const options = { new: true };
  const update = {
    $set: {
      "members.$.email": email,
      "members.$.name": name,
      "members.$.role": role,
      "members.$.twitter": twitter,
      "members.$.facebook": facebook,
      "members.$.linkedin": linkedin
    }
  };

  try {
    const result = await TeamModel.findOneAndUpdate(query, update, options);

    if (!result) {
      return res.status(400).send("No member found for the email");
    }
    res.send(result);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong");
  }
};

Сначала попробуйте эту функцию, ничего не меняя, после того, как вы увидите, что она работает, вы можете внести изменения в приложение c.

Также я заметил небольшую пробу в определении вашей схемы , вы должны использовать опции minlenght и maxlength для типа String вместо min и max.

0 голосов
/ 13 марта 2020

TeamModel не имеет свойства с именем email, name et c (см. Переменную обновления). Ваш запрос на обновление должен выглядеть следующим образом:

const update = {
  $set: {
    'members.$.email': email
  }
};

Это $ важно, потому что members - это массив.

Надеюсь, это поможет.

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