小urrent behavior:
let schema = new Schema({ ... });
let Model = mongoose.model('ModelName', schema);
new Model({...}).save();
After it we have document like this:
{
"_id" : "SyeTOtiYX",
...
"createdAt" : ISODate("2018-09-28T10:55:51.603Z"),
"updatedAt" : ISODate("2018-09-28T10:55:51.603Z")
}
createdAt
and updatedAt
timestamps are set at the same time, when I have created document
Expected behavior:
Only createdAt
should be seted during creation (updatedAt
should not be seted).
I think issue is here: https://github.com/Automattic/mongoose/blob/b41f93c0fc073c8a702f4c2101ed42d09705a5ca/lib/schema.js#L842-L852
mongoose: 5.2.18
Node.js: 8.11.4
MongoDB: 3.6.6
This is expected behavior for Mongoose. We count initial creation as an update for timestamps so you don't need extra logic for querying for all documents that have been updated since a certain time. What about this behavior is causing a problem for you?
@vkarpov15
Some causes when it may be needed:
Also e.g. sequelize
has such behavior.
It would be nice to have some setting for control this behavior. What do you think?
@andrew-polyansky Since you're on mongodb 3.6.6, you can use the $expr
operator to test the equality of thecreatedAt
and updatedAt
fields to get this now, here's a contrived example.
@vkarpov15 It might be nice to be able to configure this behavior in the future, especially if the $expr
operation from my example is noticeably slower on larger collections than the alternative of querying for docs with { updatedAt: null }
or { updatedAt: { $exists: false } }
etc.
I'm struggling to think of a realistic case where I want to find documents that were created and not updated, or updated after creation. In my experience, timestamps are used almost exclusively for newsfeeds (where you only care about createdAt
) and clients polling for updates (where you only care about updatedAt
). Can you provide an example of where you would want data that has not been updated since it was created? I don't doubt there is one, I'm just trying to educate myself :)
I suppose we could support an option like this:
schema.set(timestamps, {
createdAt: true,
updatedAt: { path: 'updatedAt', setOnInsert: false }
});
@vkarpov15 Thanks a lot for enhancement this.
Just imagine some Admin control panel that has many entities and rules. And you as Admin should know who create or update some rule and when it was.
For some causes you don't need know who, but you must know when. E.g. this may apply to information that is rapidly becoming obsolete (seasonal discounts, promotions, etc.)
IMO for these rare cases you could do many things with the way mongoose is right now.
You could, as already suggested, try to query for documents where createdAt != updatedAt
or you could just override the default method and code (via hook) that on each UPDATE query the field is updated, so this way on CREATION it will not be created/filled.
@vkarpov15 i appreciate your idea of creating a switch for that, but i think in these cases you could create many switches for every edge case and end up with a mess of settings rarely used :/
@mhombach I appreciate the concern, but querying for docs where createdAt !== updatedAt
is tricky and slow, and I think we should err on the side of adding a switch unless there's a clear reason not to.
and now, today, is this issue still open?
@tunglt1810 Well, did you look up the docs? If you see some switch setting there, it is not open. If you don't see something like that, it seems to be still open :)
There is still the easy workaround of using another default-value and/or hooks.
Hi, you should consider using the "timestamps" option that comes with Mongoose.
It automatically sets both the createdAt and updatedAt time values accordingly on document update.
const clientSchema = new mongoose.Schema({
email: String
}, { timestamps: true }
);
const Client = mongoose.model('Client', clientSchema);
const user = await Client.create({ email: '[email protected]' });
user.createdAt; // 2020-07-06T20:36:59.414Z
user.updatedAt; // 2020-07-06T20:36:59.414Z
Subsequently,
user.email = '[email protected]';
await user.save();
user.createdAt; // 2020-07-06T20:36:59.414Z
user.updatedAt; // 2020-07-06T20:37:09.071Z
@olucheye I think you did not read the initial post? Your answer does not make any sense here as it doesn't answer the question.
Of course they are both set when the record is created. Thats how databases work. What planet have you been on?
Of course they are both set when the record is created. Thats how databases work. What planet have you been on?
@ekerner-com
If you carefully read the problem explanation, you will see, that your comment is not 100% relating to it (not mentioning the bad words in your last sentence).
The problem here is, that semantically "updated at" can be interpreted as being something different than "created at".
When you first create an entry, you can store the current timestamp in "createdAt" and only after another update to that entry, write some timestamp to "updatedAt". This is what this issue here is about.
If you are not familiar with MongoDB to that extend, I suggest reading into this topic, as it's really helpful in a lot of applications.
Bro
Of course they are both set when the record is created. Thats how databases work. What planet have you been on?
@ekerner-com
If you carefully read the problem explanation, you will see, that your comment is not 100% relating to it (not mentioning the bad words in your last sentence).
The problem here is, that semantically "updated at" can be interpreted as being something different than "created at".
When you first create an entry, you can store the current timestamp in "createdAt" and only after another update to that entry, write some timestamp to "updatedAt". This is what this issue here is about.
If you are not familiar with MongoDB to that extend, I suggest reading into this topic, as it's really helpful in a lot of applications.
I read the question fine, so did everyone else, I get that you're saying that in your opinion updated should only be adjusted when an existing record is updated, by your interpretation of the definition of the word "update".
However were all trying to tell you that in database record management, in Mongo and and every other database Iv ever worked with in y 35+ year IT career, the updated (aka changed aka modified) field is interpreted to mean any change in state of the record including creation.
Even in databases which don't automatically provide and set this field we conventionally set it manually upon record creation to the same timestamp as the created field.
If the developers of Mongo change this age-old tradition to suit your preferred interpretation it will break much existing code which is relying on the updated/modified/changed timestamp.
If you make a workaround in your database to support your way its fine, except its non conventional and may be a "gotcha" for future developers trying to debug or maintain your code.
I recommend just go with the convention.
For example "shift" on an array conventionally removes and returns the first element. If I make a shift function which bit shifts every element of the array because I think that shift should mean that, then I'm just making less readable and less maintainable code which does other than what is expected, so I wouldn't do it.
Not meaning to offend you, just stating that the number of years someone has worked in IT means nothing in terms of expertise. I think we both can agree on that.
Following up:
If the developers of Mongo change this age-old tradition to suit your preferred interpretation it will break much existing code
Summed up: Not changing something because it would mean other developers to adapt, isn't a long-lasting concept. If you see technical disadvantages in daily use for this change, everyone here is happy to discuss them. Otherwise, I would encourage an open mind for changes and thoughts.
Not meaning to offend you, just stating that the number of years someone has worked in IT means nothing in terms of expertise. I think we both can agree on that.
Following up:
- I am not the creator of this issue. But I am still able to understand the creator's question about being able to separate the "create"-timestamp from the "update"-timestamp. An update-process is something different than a creation process. No need to give examples or further explanation I hope, since everyone here is working in the same field.
- Just because something was done 30 years ago in the databases that time, doesn't necessarily conclude, that it's still a good practice. Otherwise, MongoDB itself and most of the modern tech would not be existing nowadays. So I am pretty sure that everyone, working in/with modern tech, is re-challenging previously made decisions from time to time and evaluate, if the decisions made before still hold up to the demand and knowledge of today.
- Technically speaking, storing the "update"-timestamp on the creation-process is just duplicated resources while providing no more information on the dataset. While on the other hand a missing "update"-timestamp has some expression and so holds information by even using fewer resources (storage, transmission, processing, etc).
If the developers of Mongo change this age-old tradition to suit your preferred interpretation it will break much existing code
- Yes. This is called "breaking change" and is a normal concept of software development. It's nothing wrong or bad, since there is a defined and thought through process on both ends (developers of a library and developers using a library), which includes notifying early and providing enough information for every developer to adapt to the new changes.
- Not going into details about your shift-example, because nobody here suggested to just change something because someone interprets a term differently. We are just discussing an idea and challenging an old concept, which might not hold up to today's agreements on software development.
Summed up: Not changing something because it would mean other developers to adapt, isn't a long-lasting concept. If you see technical disadvantages in daily use for this change, everyone here is happy to discuss them. Otherwise, I would encourage an open mind for changes and thoughts.
Noobs. Have you heard of Mary Mary quite contrary? I believe you would argue either way, if I said water was wet youde argue it dry. As for years and practice = expertise, yes, they go hand in hand, go get some.
@ekerner-com I was nice and neutral to you and everyone else here. Since you are now falling back to middle school language and behavior, any further discussion with you, from my side, is done.
Most helpful comment
@mhombach I appreciate the concern, but querying for docs where
createdAt !== updatedAt
is tricky and slow, and I think we should err on the side of adding a switch unless there's a clear reason not to.