Подтвердить что ты не робот

Не удалось обновить модель мангуста

У меня есть странная проблема, которая меня озадачивает. У меня есть модель:

var Model = new Schema({
    name: String,
    variations: Array
});

Запись изменений выглядит следующим образом:

[ {code: '', price: '' }, {code: '', price: '' }]

Мне нужно добавить новое поле - скажем "цвет". Поэтому я делаю это для пакетного обновления:

Model.find().exec(function(err, products) {
    if (!err) {
        products.forEach(function(p) {
            for(var i = p.variations.length - 1; i >= 0; i--) {
                p.variations[i]['color'] = 'red';
                // This shows all existing variations 
                // with the new color feed - correct
                console.log(p.variations[i]);
            }
            p.save(function(err) {
                if (!err) {
                    console.log("Success");
                } else {
                    console.log(err);
                }
            });
        });     
    }
});

Однако поле "цвет" не задано - если я снова пройдусь и закомментирую строку p.variations[i]['color'] = 'red';, то она не будет отображаться. Я не могу понять, почему он это делает. У меня есть событие onSave, которое запускается правильно, чтобы оно сохранялось. У меня также нет никакой проверки структуры вариаций - т.е. Нет кода, который разрешает только код и цену. Я, очевидно, что-то пропустил, но через пару часов у меня кончились идеи.

4b9b3361

Ответ 1

При изменении содержимого нетипизированного поля Array, такого как variations, вам необходимо уведомить Mongoose о том, что вы изменили его значение, вызвав markModified(path) на измененном документе или последующем вызове save() сохранить его. См. документы.

  for(var i = p.variations.length - 1; i >=0; i--) {
    p.variations[i]['color'] = 'red';
  }
  p.markModified('variations');
  p.save(function(err) { ...

Ответ 2

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

for(var i = p.variations.length - 1; i >=0; i--) {
  p.variations[i].set({"color":"red", "code":"herr"});
  // or
  p.variations[i].set("color":"red");
  p.variations[i].set("code":"herr");
}

Альтернативой было бы изменить значение поля по-старому, не перебирая сеттера, а затем вручную пометить его как измененное: p.markModified('variations');

По-моему, вы всегда должны использовать сеттер, так как это более читаемо. Вы можете просто передать объект json, содержащий все ваши изменения в параметре, и он будет безопасно обновлять поля, которые вы действительно хотите изменить.