_First: A workaround to overcome this issue:_
Model.findOne({id: 'blabla'}).select('email password createdAt').lean().exec()
I use an createdAt
field -which has an expires (TTL 24h
) and a default (Date.now
) value- in my Users
model to store the creating date info of the new created users.
If the user activates the account the system removes the createdAt
field.
If the user doesn't activate the account the system remove the account from Users
collection after 24 hours.
In my authentication operations, I check the existing of createdAt
field firstly.
If the user is not activated I show a message like Account is not activated.
When I try FindOne
method for purpose of the above authentication procedure, I get Date.now
value although there is no a createdAt
field in the document because of the user has activated his account.
createdAt
field in my User
model:
createdAt: { type: Date, expires: '24h', default: Date.now },
My method:
Users.findOne({email: username}, 'email, password, createdAt', function(err, user) {
By using the above method createdAt
value returns at every time.
ps: i searched the issue but i couldn't anything.
That's just how defaults work, when there isn't a createdAt
field in the doc mongoose will add one. If you only want to add createdAt
when creating a new doc:
schema.pre('save', function(next) {
if (this.isNew) {
this.createdAt = Date.now();
}
next();
});
Also, I wouldn't recommend separating the fields in your projection Users.findOne({email: username}, 'email, password, createdAt' /** <-- remove commas here */)
with commas.
Stumbled upon the same problem.
@vkarpov15 it should not work that way. Although default value is set on saving it is misleading to set it when find
the document, because it should actually return exact data stored in DB, isn't it? I would vote for reopening the issue.
Not necessarily, mongoose has a lot of places where the document doesn't represent the exact data stored in the db: getters, virtuals, etc. Either way, we assert on this behavior and changing it would break a lot of people's code, so we won't change it unless there's a lot of demand to change it. Here's a workaround:
createdAt: {
type: Date,
default: function() {
if (this.isNew) { return new Date(); }
return undefined;
}
}
This will make it so that createdAt
is only set when saving to the database, but it'll be undefined
if you loaded a doc from the db and createdAt
isn't set.
Most helpful comment
Stumbled upon the same problem.
@vkarpov15 it should not work that way. Although default value is set on saving it is misleading to set it when
find
the document, because it should actually return exact data stored in DB, isn't it? I would vote for reopening the issue.