Mongoose: FindOne retorna o valor padrão do campo inexistente.

Criado em 23 jul. 2016  ·  3Comentários  ·  Fonte: Automattic/mongoose

_Primeiro: Uma solução alternativa para superar esse problema: _
Model.findOne({id: 'blabla'}).select('email password createdAt').lean().exec()

edição:

Eu uso um campo createdAt - que tem uma expiração (TTL 24h ) e um valor padrão ( Date.now ) - em meu modelo Users para armazenar a criação informações de data dos novos usuários criados.

Se o usuário ativar a conta, o sistema remove o campo createdAt .
Se o usuário não ativar a conta, o sistema removerá a conta da coleção Users após 24 horas.

Em minhas operações de autenticação, eu verifico a existência do campo createdAt primeiro.
Se o usuário não estiver ativado, eu mostro uma mensagem como Account is not activated.

Quando tento o método FindOne para o propósito do procedimento de autenticação acima, obtenho o Date.now embora não haja um campo createdAt no documento porque o usuário ativou sua conta .

createdAt campo em meu modelo User :
createdAt: { type: Date, expires: '24h', default: Date.now },

Meu método:
Users.findOne({email: username}, 'email, password, createdAt', function(err, user) {

Usando o método acima, createdAt value retorna a cada vez.

ps: pesquisei o problema, mas não consegui nada.

Comentários muito úteis

Tropecei no mesmo problema.
@ vkarpov15 não deve funcionar dessa forma. Embora o valor padrão seja definido ao salvar, é enganoso defini-lo quando find o documento, porque ele deve realmente retornar os dados exatos armazenados no banco de dados, não é? Eu votaria pela reabertura da questão.

Todos 3 comentários

É assim que os padrões funcionam, quando não há um campo createdAt no documento, o mongoose adicionará um. Se você deseja adicionar apenas createdAt ao criar um novo documento:

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

Além disso, eu não recomendaria separar os campos em sua projeção Users.findOne({email: username}, 'email, password, createdAt' /** <-- remove commas here */) com vírgulas.

Tropecei no mesmo problema.
@ vkarpov15 não deve funcionar dessa forma. Embora o valor padrão seja definido ao salvar, é enganoso defini-lo quando find o documento, porque ele deve realmente retornar os dados exatos armazenados no banco de dados, não é? Eu votaria pela reabertura da questão.

Não necessariamente, o mongoose tem muitos lugares onde o documento não representa os dados exatos armazenados no banco de dados: getters, virtuais, etc. De qualquer forma, afirmamos esse comportamento e alterá-lo quebraria o código de muitas pessoas, então não o mudaremos, a menos que haja muita demanda para mudá-lo. Aqui está uma solução alternativa:

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

Isso fará com que createdAt seja definido apenas ao salvar no banco de dados, mas será undefined se você carregou um documento do banco de dados e createdAt não definir.

Esta página foi útil?
0 / 5 - 0 avaliações