Mongoose: Метод обновления модели не уважает валидаторов

Созданный на 24 апр. 2012  ·  59Комментарии  ·  Источник: Automattic/mongoose

Я могу использовать метод model.Update для обновления до любого значения независимо от ограничений схемы.

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

Ожидаемое поведение заключалось в выдаче ошибки, если обновленное значение не проверялось.

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

new feature

Самый полезный комментарий

+1

Совершенно не интуитивно понятно, что в обновлении не используются: значения по умолчанию, сеттеры, проверка и перечисления. Какая польза от схемы, если основные операции ей не соответствуют.

Все 59 Комментарий

вы можете включить параметр схемы strict который будет игнорировать любые недопустимые пути схемы и обновлять остальные. ошибки не возникает.

новая схема ({..}, {strict: true})

есть аналогичный запрос на перенос, ожидающий слияния, который выдается при установке путей, которые не существуют в схеме, но он не генерируется во время model.update . возможно, нам следует добавить это в PR выше и передать ошибку в обратный вызов.

Еще раз привет, спасибо за быстрый ответ.

Я имел в виду не недопустимые пути, а ограничение в рамках определенного пути.

Возьмите этот пример

var User = new Schema ({
имя пользователя: {
тип: String,
нижний регистр: истина,
обрезать: правда,
уникальный: правда
},
имя: {
тип: String,
обрезать: правда,
требуется: true,
уникальный: ложь,
index: true
},
пароль: {
тип: String,
требуется: true,
выберите: false,
установить: зашифровать
},
роль: {
тип: String,
"по умолчанию": 'пользователь',
"перечисление": ['пользователь', 'администратор', 'корень']
},
созданный: {
тип: Дата,
"по умолчанию": Date.now
}
}, {strict: true});

users.update ({"username": "test"}, {"role": "thisShowldFail"}, function (err, val) {
...
});

Обратите внимание, что теперь у «тестового» пользователя есть роль «thisShowldFail» даже при включенной опции строгой схемы.
Не следует обновлять перечисления уважения и другие подобные параметры?

Вы правы, он должен проверять перечисления. Я думал, что где-то есть билет на это.

+1, не могу использовать #update из-за этой проблемы.

Возможно ли, чтобы .update делал все, что делал бы новый документ + .save?

  • значения по умолчанию
  • сеттер
  • пользовательские проверки
  • перечислить

если используется опция upsert, также

  • требуется

не сейчас

Я имею в виду, возможно ли / планируется ли реализовать ...? :)

это могло бы быть хорошо. связанные # 472

+1

Совершенно не интуитивно понятно, что в обновлении не используются: значения по умолчанию, сеттеры, проверка и перечисления. Какая польза от схемы, если основные операции ей не соответствуют.

+1

Я люблю мангуста, но если он не проверяет обновления, это для меня гораздо менее полезно. У меня большие документы, и я не хочу загружать их только для проверки.

Это я вскакиваю. Я немного ныряю, пытаясь реализовать это.
Цель - получить:

  • значения по умолчанию
  • сеттер
  • проверки
  • перечислить
  • требуется

Даже не уверен, что добьюсь успеха, но попробую. Начну с валидаторов.

Пожелай мне удачи!

Merc.

+1

+1

Было бы здорово, если бы .update поддерживал валидации.

Подъем +1

Неровная неровность +1

Пожалуйста, добавьте проверки при обновлении!

+1

Изменить: -2, потому что я не думаю, что мангуст должен отвечать за проверку. Если вам нужна проверка, вам следует подумать об использовании другой специализированной библиотеки, например, с использованием проверки схемы JSON

@thalesfsp Да. Это уже предпринималось в прошлом, но правила становятся очень нестабильными, потому что в памяти нет документа, и в некоторых случаях они не работают, что приводит к непоследовательному и непоследовательному поведению.

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

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

+1 Bump, это была бы очень полезная функция - при выполнении обновлений я хотел бы, чтобы минимальные / максимальные значения и т. Д. Соблюдались из схемы - в противном случае я использую много шаблонной логики для того, что может сделать мангуст

Было бы здорово увидеть это. На данный момент мой обходной путь - найти объект, изменить поля и затем сохранить его, что запускает промежуточное ПО для проверки. Согласно документам :

Tank.findById(id, function (err, tank) {
  tank.size = 'large';
  tank.save(function (err) {
   // Document updated, do something with it
  });
});

Я понимаю, что это сложно, поскольку команда update делегирует непосредственно Mongo, а полный документ не находится в памяти для проверки. Таким образом, подход, предложенный @BrianHoldsworth, кажется хорошим местом для начала, анализируя схему, выполняя проверки только в отношении полей, которые должны быть обновлены.

@aheckmann, не могли бы вы предоставить нам более подробную информацию о предыдущих (неудачных) усилиях по реализации, чтобы тот, кто попытается установить этот патч, больше не совершил те же ошибки?

В основном меня интересуют настраиваемые валидаторы и правила перечисления, применяемые к обновлению. Думаю, другие ограничения схемы уже должны были быть применены при сохранении документа. Имеет ли смысл такое упрощение проблемы до перечислений и валидаторов и устраняет ли необходимость иметь какой-либо документ во время обновления?

@BrianHoldsworth: Думаю, это упрощение. Что произойдет, если поле с ограничением проверки required: true будет обновлено до пустой строки? Нам это понадобится, чтобы вызвать ошибку проверки.

Меня это тоже интересует. Возможно, можно было бы написать плагин для переопределения метода .update () и запуска проверки? Таким образом может быть реализовано даже частичное решение. С другой стороны, если бы он был в ядре, можно было бы ожидать, что он будет обрабатывать все виды проверки и будет на 100% надежным.

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

+1 подбрось это.

Решение Брайана кажется довольно элегантным. Хотел бы получить уведомление, когда патчи выйдут на бета-версию.

+1

нужно это +1

+1

+1

+1

+1

В 3.9.3 update() будет иметь 2 специальных параметра: setDefaultsOnInsert и runValidators , которые установят значения по умолчанию и запустят валидаторы по вашему запросу. Смотрите, например, тесты , реальных документов пока нет :(

Большое вам спасибо - это отличное решение!

@ vkarpov15 Я использовал ваш код, чтобы также применить проверку к findOneAndUpdate. См. PR # 2393.

Привет, вы знаете, когда выйдет стабильная версия 3.9, чтобы использовать проверку при обновлении?

Спасибо

@AlexandreAWE хороший вопрос. В настоящее время я завершаю работу над версией 4.0 и бета-тестированием ветки 3.9.x, но сейчас это вопрос «когда все будет готово». Я надеюсь выпустить RC до Рождества.

@ vkarpov15 Как дела на стабильной версии 3.9.x? Было бы здорово иметь проверки обновлений вместо того, чтобы каждый раз находить и сохранять для моего текущего проекта.

@andrewholsted ждет стабилизации драйвера mongodb 2.0 и сервера mongodb 2.8 - мы надеемся, что это произойдет в этом месяце, но не может выпустить 4.0 без поддержки последней версии mongodb и последнего драйвера. См. Мой блог для получения более подробной информации.

Потенциально глупый вопрос, но почему бы не взять обновляемые данные и не проверить их на соответствие схеме, прежде чем переходить к mongodb?

Кроме того, +1

отметьте и подождите

Не могу дождаться, пока 3.9 станет стабильной :)

Эта функция еще не реализована? С нетерпением жду 3.9 .. Вэнь будет ли она в наличии?

Вы можете npm install mongoose@unstable чтобы получить нестабильную версию. Текущее расчетное время прибытия для 4.0 - 25 марта - хорошее место, чтобы проверить, это страница этапов.

Только вчера вечером столкнулся с этой проблемой. Рад, что я не один такой! Я очень рад, что это изменение будет выпущено, спасибо за все, что вы делаете!

+1

Не знаю, почему эта проблема помечена как закрытая. Я все еще сталкиваюсь с этим.

На самом деле я не уверен, что это работает при проверке перечисления для findOneAndUpdate (), даже если для runValidators установлено значение true.

@ m1cah, пожалуйста, приведите пример, демонстрирующий, что вы пытаетесь сделать. У нас есть тесты на это, и они проходят ...

@ vkarpov15 Я считаю, что это короткий пример, демонстрирующий это: http://code.runnable.com/VYhGbVhereIYdbst/update-validation-enum-for-mongoose-and-databases

Что ж, одна проблема заключается в том, что в приведенном выше примере используется доисторическая версия мангуста:

root<strong i="6">@runnable</strong>:~# head node_modules/mongoose/package.json                                                                                                                 
{                                                                                                                                                                         
  "name": "mongoose",                                                                                                                                                     
  "description": "Elegant MongoDB object modeling for Node.js",                                                                                                           
  "version": "3.6.14",                                                                                                                                                    
  "author": {                                                                                                                                                             
    "name": "Guillermo Rauch",                                                                                                                                            
    "email": "[email protected]"                                                                                                                                   
  },                                                                                                                                                                      
  "keywords": [                                                                                                                                                           
    "mongodb",  

Попробуйте перейти на 4.x, и он должен работать.

Вы уверены, что он работает с перечислением и методом findOneAndUpdate?
На мангусте 4.2.6 кажется, что он не работает, я могу установить плохое значение.

Схема:

var UserSchema = new Schema({
    first_name: {
        type: String,
        required: true,
    },
    last_name: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        unique: true,
        required: true,
    },
    embededData: [{
        type: {
            type: String,
            enum: ['value1', 'value2', 'value3']
            required: true
        }
    }]
}, { strict: true });

FindOneAndUpdate метод:

UserModel.findOneAndUpdate(
    {_id: uid}, 
    {$push: {embededData: data}}, 
    { runValidators: true }, function(err) {
});

Затем я могу нажать embededData.type = 'Panda';

См. Документацию по валидатору обновлений и # 2933 - валидаторы обновлений не работают на $push , только на $set и $unset

+1

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

Например, этот фрагмент кода:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/myTestDB');

var db = mongoose.connection;

db.on('error', function (err) {
console.log('connection error', err);
});
db.once('open', function () {
console.log('connected.');
});

var Schema = mongoose.Schema;
var userSchema = new Schema({
  _id : String,
  name : {
    type: [String],
    validate: {
        validator: function (str) {
            return str.length > 1
        }
    },
  }
});


var User = mongoose.model('User', userSchema);

User.findOneAndUpdate({"name": ["John", "Doe"]}, { 
  $setOnInsert: {
    name: ["John"],
  },
}, { runValidators: true, upsert: true, new: true }, function (err, data) {
  if (err) {
    return console.log(err);
  } else {
    // console.log(data.validateSync())
    return console.log('Updated', data);
  }
});

позволит вам обновить пользователя, чтобы у него было поле name ["John"] без выдачи каких-либо ошибок, даже несмотря на то, что пользовательский валидатор, который я включил, явно запрещает любой массив имен длиной меньше или равной 1. Параметр Сам валидатор работает нормально, о чем можно судить по тому факту, что если вы раскомментируете строку console.log(data.validateSync()) , тем самым заставив выполнение проверки, он фактически вернет соответствующее сообщение об ошибке. Проблема в том, что эта проверка не выполняется в вызове findOneAndUpdate() , несмотря на то, что я включил опцию runValidators=true .

Похоже на ошибку, можете ли вы выделить для этого отдельный вопрос?

Спасибо

Есть ли какое-нибудь исправление для вышеуказанной проблемы? @ vkarpov15

@ Saravanan90, пожалуйста, прекратите комментировать давно закрытые вопросы без какой-либо значимой информации. Откройте отдельную проблему с примерами кода.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги