Mongoose: FindOne возвращает значение по умолчанию для несуществующего поля.

Созданный на 23 июл. 2016  ·  3Комментарии  ·  Источник: Automattic/mongoose

_First: обходной путь для решения этой проблемы: _
Model.findOne({id: 'blabla'}).select('email password createdAt').lean().exec()

проблема:

Я использую поле createdAt которое имеет срок действия (TTL 24h ) и значение по умолчанию ( Date.now ) в моей модели Users для хранения созданных информация о дате новых созданных пользователей.

Если пользователь активирует учетную запись, система удаляет поле createdAt .
Если пользователь не активирует учетную запись, система удалит ее из коллекции Users через 24 часа.

В своих операциях аутентификации я сначала проверяю наличие поля createdAt .
Если пользователь не активирован, я показываю сообщение типа Account is not activated.

Когда я пробую FindOne метод для вышеупомянутой процедуры аутентификации, я получаю значение Date.now хотя в документе нет поля createdAt потому что пользователь активировал свою учетную запись. .

Поле createdAt в моей модели User :
createdAt: { type: Date, expires: '24h', default: Date.now },

Мой метод:
Users.findOne({email: username}, 'email, password, createdAt', function(err, user) {

Используя вышеуказанный метод, createdAt значение возвращается каждый раз.

ps: я искал проблему, но ничего не смог.

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

Наткнулся на такую ​​же проблему.
@ vkarpov15 так работать не должно. Хотя значение по умолчанию устанавливается при сохранении, вводить его в заблуждение при find документа, потому что он должен фактически возвращать точные данные, хранящиеся в БД, не так ли? Я бы проголосовал за повторное открытие вопроса.

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

Вот как работают значения по умолчанию: когда в документе нет поля createdAt добавит его. Если вы хотите добавить только createdAt при создании нового документа:

schema.pre('save', function(next) {
  if (this.isNew) {
    this.createdAt = Date.now();
  }
  next();
});

Также я бы не рекомендовал разделять поля в вашей проекции Users.findOne({email: username}, 'email, password, createdAt' /** <-- remove commas here */) запятыми.

Наткнулся на такую ​​же проблему.
@ vkarpov15 так работать не должно. Хотя значение по умолчанию устанавливается при сохранении, вводить его в заблуждение при find документа, потому что он должен фактически возвращать точные данные, хранящиеся в БД, не так ли? Я бы проголосовал за повторное открытие вопроса.

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

createdAt: {
  type: Date,
  default: function() {
    if (this.isNew) { return new Date(); }
    return undefined;
  }
}

Это сделает так, что createdAt устанавливается только при сохранении в базу данных, но это будет undefined если вы загрузили документ из базы данных, а createdAt не установленный.

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