Mongoose принимает null для поля Number

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

port:{
    type:Number,
    default:1234
}

Если я не получаю никакого значения через свой API, для него устанавливается значение 1234. Однако, если кто-то отправляет null, он принимает null и сохраняет в базе данных.

Разве он не должен скрывать null в 1234? null это не число! Я неправильно понимаю?

Я рассматриваю решение, представленное здесь, но я не хочу добавлять дополнительный код для чего-то, что должно работать без него (если только я не я ошибаюсь, и он не должен преобразовывать null в 1234)


person Dushyant Bangal    schedule 20.07.2017    source источник
comment
Это скорее JavaScript-артефакт, в котором типы в мангусте основаны на. Таким образом, это зависит от того, можете ли вы либо просто выдать исключение (что вы можете сделать с помощью простого валидатора), либо заменить null значением по умолчанию, где оно предоставляется, что делается в предварительных ловушках, как вы упомянули. Или вместо этого убедитесь, что входные данные равны undefined вместо null, и тогда значения по умолчанию будут работать как положено.   -  person Neil Lunn    schedule 20.07.2017
comment
Помог ли вам мой ответ ниже? Любые комментарии?   -  person rsp    schedule 23.07.2017


Ответы (2)


Смотрите комментарии в этом выпуске:

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

(речь идет о датах, но ее можно применить и к числам.)

Ваши варианты:

  • добавить required в поле
  • добавить пользовательский валидатор, который отклонит его
  • использовать хуки/промежуточное ПО для решения проблемы

Вам может сойти с рук хук с предварительным сохранением или пост-валидацией (или какой-то другой) вроде этого:

YourCollection.pre('save', function (next) {
  if (this.port === null) {
    this.port = undefined;
  }
  next();
});

но, вероятно, вам придется использовать что-то вроде:

YourCollection.pre('save', function (next) {
  if (this.port === null) {
    this.port = 1234; // get it from the schema object instead of hardcoding
  }
  next();
});

См. также этот ответ, чтобы узнать, как заставить null запускать значения по умолчанию при вызове функции:

К сожалению, Mongoose нельзя настроить для обработки null как undefined (с каким-то «ненулевым» параметром или чем-то подобным), потому что иногда вы работаете с данными, которые вы получили в запросе как JSON, и иногда это может преобразовать undefined в ноль:

> JSON.parse(JSON.stringify([ undefined ]));
[ null ]

или даже добавить значения null там, где не было (явно) undefined:

> JSON.parse(JSON.stringify([ 1,,2 ]));
[ 1, null, 2 ]
person rsp    schedule 20.07.2017
comment
Хороший ответ. Спасибо :) - person Bogdan M.; 10.05.2018

Как поясняется в официальной документации mongoose здесь

Number Чтобы объявить путь как число, вы можете использовать либо глобальный конструктор Number, либо строку 'Number'.

const schema1 = new Schema({ age: Number }); // age will be cast to a Number
const schema2 = new Schema({ age: 'Number' }); // Equivalent
const Car = mongoose.model('Car', schema2);
There are several types of values that will be successfully cast to a Number.
new Car({ age: '15' }).age; // 15 as a Number
new Car({ age: true }).age; // 1 as a Number
new Car({ age: false }).age; // 0 as a Number
new Car({ age: { valueOf: () => 83 } }).age; // 83 as a Number

Если вы передаете объект с функцией valueOf(), которая возвращает число, Mongoose вызовет ее и присвоит возвращаемое значение пути.

Значения null и undefined не приводятся.

NaN, строки, приводящие к NaN, массивы и объекты, не имеющие функции valueOf(), приведут к ошибке CastError.

person Deeksha Sharma    schedule 26.04.2019