При обновлении профиля пользователя некоторая информация стирается из БД Mongodb - PullRequest
0 голосов
/ 21 марта 2019

Когда я обновляю свой профиль пользователя, область поля, которая находится внутри местоположения на моей модели пользователя, стирается, это моя модель пользователя, где вы можете видеть окрестности внутри местоположения:

const userSchema = new Schema({

  name: {
    type: String,
    required: 'Please supply a name',
    trim: true
  },
   location: {
    type: {
      type: String,
      default: 'Point'
    },
    coordinates: [{
      type: Number,
      required: 'You must supply coordinates!'
    }],
    address: {
      type: String,
      required: 'You must supply an address!'
    },
    vicinity: {
      type: String,
    },
  },
});

Тогда у меня есть контроллер, который обновляет пользователя, где у меня есть объект обновлений, а окрестность здесь не нужна, поскольку я не хочу обновлять его, я просто хочу сохранить окрестность в регистре, а не обновлять его:

exports.updateAccount = async (req, res) => {
  req.body.location.type = 'Point';

  const updates = {
    email: req.body.email,
    name: req.body.name,
    photo: req.body.photo,
    genres: req.body.genres,
    musicLinks: req.body.musicLinks,
    location: {
      type: req.body.location.type,
      coordinates: [
        req.body.location.coordinates[0],
        req.body.location.coordinates[1],
      ],
      address: req.body.location.address,
      // vicinity: req.body.location.vicinity,
    }
  };

  if(!updates.photo) delete updates.photo

  const user = await User.findOneAndUpdate(
    { _id: req.user._id },
    { $set: updates },
    { new: true, runValidators: true, context: 'query' }
  );
  req.flash('success', 'Updated the profile!');
  res.redirect('back');
};

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

Я предполагаю, что, поскольку на контроллере у меня есть объект обновлений, такой как:

 location: {
      type: req.body.location.type,
      coordinates: [
        req.body.location.coordinates[0],
        req.body.location.coordinates[1],
      ],
      address: req.body.location.address,
      // vicinity: req.body.location.vicinity,
    }

и его недостающая скорость. база данных пытается сохранить весь объект местоположения, и, поскольку поблизости нет, она удаляется.

Если это так ... как я могу сказать Монго ДБ, чтобы сохранить значение в БД и не удалять его? Спасибо

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Причина этого в том, что вы фактически обновляете поле location новым объектом. Каждый ключ в location объекте стирается, а затем переписывается - поэтому vicinity теряется.

Для достижения цели вы можете использовать синтаксис вложенного ключа:

const updates = {
  $set: {
    email: req.body.email,
    name: req.body.name,
    photo: req.body.photo,
    genres: req.body.genres,
    musicLinks: req.body.musicLinks,
    'location.type': req.body.location.type,
    'location.coordinates': [req.body.location.coordinates[0], req.body.location.coordinates[1]],
    'location.address': req.body.location.address,
  }
};

После этого:

const user = await User.findOneAndUpdate(
  { _id: req.user._id },
  updates,
  { new: true, runValidators: true, context: 'query' }
);
1 голос
/ 21 марта 2019

Это по замыслу.

Вы фактически включаете «полный объект» для location в свои аргументы для $set, и это делает просто перезаписать этого объекта. Вот как в основном работает MongoDB.

Другая часть работы MongoDB заключается в том, что когда вы намереваетесь частично обновить документ "вложенными путями", вам нужно обработать структуру этого объекта в "Точечная нотация" форма.

На самом деле, вот базовая версия того, что я собрал давным-давно, чтобы сделать именно это:

var data = {
    email: "bill@example.com",
    name: "Bill S Preston",
    photo: "",
    genres: "Music, Lyrics",
    musicLinks: "",
    location: {
      type: "Point",
      coordinates: [
        0,
        0
      ],
      address: "somewhere"
    }
};

И простая функция:

function dotNotate(obj,target,prefix) {
  target = target || {},
  prefix = prefix || "";

  Object.keys(obj).forEach(function(key) {
    if ( Array.isArray(obj[key] )) {
      return target[prefix + key] = obj[key];
    } else if ( typeof(obj[key]) === "object" ) {
      dotNotate(obj[key],target,prefix + key + ".");
    } else {
      return target[prefix + key] = obj[key];
    }
  });

  return target;
}

Запуск этой функции дает:

var updates = dotNotate(data);

{
        "email" : "bill@example.com",
        "name" : "Bill S Preston",
        "photo" : "",
        "genres" : "Music, Lyrics",
        "musicLinks" : "",
        "location.type" : "Point",
        "location.coordinates" : [
                0,
                0
        ],
        "location.address" : "somewhere"
}

И, конечно, { $set: updates } будет только частично обновлять поля, явно указанные без перезаписи.

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