Я создал учетную запись StackOverflow ПРОСТО, чтобы ответить на этот вопрос.После бесплодного поиска в сети я просто что-то написал сам.Вот как я это сделал, чтобы его можно было применить к любой модели мангуста.Либо импортируйте эту функцию, либо добавьте ее непосредственно в код, в котором выполняется обновление.
function upsertObject (src, dest) {
function recursiveFunc (src, dest) {
_.forOwn(src, function (value, key) {
if(_.isObject(value) && _.keys(value).length !== 0) {
dest[key] = dest[key] || {};
recursiveFunc(src[key], dest[key])
} else if (_.isArray(src) && !_.isObject(src[key])) {
dest.set(key, value);
} else {
dest[key] = value;
}
});
}
recursiveFunc(src, dest);
return dest;
}
Затем, чтобы вставить документ Mongoose, выполните следующие действия:
YourModel.upsert = function (id, newData, callBack) {
this.findById(id, function (err, oldData) {
if(err) {
callBack(err);
} else {
upsertObject(newData, oldData).save(callBack);
}
});
};
Для этого решения может потребоватьсяТем не менее вы получаете 2 вызова БД:
- Проверка схемы по вашей модели, потому что вы используете .save ()
- Вы можете вставлять глубоко вложенные объекты без ручного перечисления в вашемОбновите вызов, поэтому, если ваша модель изменится, вам не нужно беспокоиться об обновлении кода
Просто помните, что целевой объект всегда будет переопределять источник, даже если источник имеет существующее значение
Кроме того, для массивов, если существующий объект имеет более длинный массив, чем заменяющий его, тогда значения в конце старого массива останутся.Самый простой способ сохранить весь массив - это установить старый массив как пустой массив перед загрузкой, если это именно то, что вы собираетесь делать.
ОБНОВЛЕНИЕ - 16.01.2016 я добавилдополнительное условие, если существует массив примитивных значений, Mongoose не понимает, что массив обновляется без использования функции "set".