You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Access document in pre hook query middleware #8218
In a pre hook for findOneAndUpdate I need to get the document being saved. I can see there is an issue that was closed previously for this that simply had a link to the documentation, however the documentation for this is not straight forward at all. It does describe how "this" functions in query middleware but I do not see anywhere in the documentation that says how to actually get the document in query middleware.
I generally find the Mongoose documentation to be very difficult to read which makes it significantly harder and less attractive to use Mongoose.
Can someone please indicate how to access the document in the a pre hook for query middleware?
I am not sure if I understand correctly, but I believe accessing the document before updating it through a findOneAndUpdate hook is not possible, as this operation is an atomic one and is not being split into multiple "parts", therefor mongoose does not actually "know" what the document looks like while handling this query. Because of this, the "this" only refers to the query and not the document. However, you can of course first fetch the object through findOne or findById, and then call "save()" on it, which will give you the document in the pre('save') hook of the model.
@BenSower is right, you would need to execute a separate query to get the document being updated in pre('findOneAndUpdate'), because findOneAndUpdate is a single atomic operation sent to mongodb. You can access the document in post('findOneAndUpdate') though
This is the documentation:
You cannot access the document being updated in pre('updateOne') or pre('findOneAndUpdate') query middleware. If you need to access the document that will be updated, you need to execute an explicit query for the document.
schema.pre('findOneAndUpdate', async function() {
const docToUpdate = await this.model.findOne(this.getQuery());
console.log(docToUpdate); // The document that `findOneAndUpdate()` will modify
});
However, if you define pre('updateOne') document middleware, this will be the document being updated. That's because pre('updateOne') document middleware hooks into Document#updateOne() rather than Query#updateOne().
Actually @MichaelMikeJones the docs describe the behavior correctly, they mention the difference between pre('updateOne') query middleware and document middleware.
Activity
BenSower commentedon Oct 7, 2019
I am not sure if I understand correctly, but I believe accessing the document before updating it through a findOneAndUpdate hook is not possible, as this operation is an atomic one and is not being split into multiple "parts", therefor mongoose does not actually "know" what the document looks like while handling this query. Because of this, the "this" only refers to the query and not the document. However, you can of course first fetch the object through findOne or findById, and then call "save()" on it, which will give you the document in the pre('save') hook of the model.
vkarpov15 commentedon Oct 9, 2019
@BenSower is right, you would need to execute a separate query to get the document being updated in pre('findOneAndUpdate'), because findOneAndUpdate is a single atomic operation sent to mongodb. You can access the document in post('findOneAndUpdate') though
miadabdi commentedon Sep 14, 2020
This is the documentation:
You cannot access the document being updated in pre('updateOne') or pre('findOneAndUpdate') query middleware. If you need to access the document that will be updated, you need to execute an explicit query for the document.
However, if you define pre('updateOne') document middleware, this will be the document being updated. That's because pre('updateOne') document middleware hooks into Document#updateOne() rather than Query#updateOne().
vkarpov15 commentedon Sep 19, 2020
@MichaelMikeJones I opened up #9434 to fix that 👍
vkarpov15 commentedon Sep 22, 2020
Actually @MichaelMikeJones the docs describe the behavior correctly, they mention the difference between
pre('updateOne')query middleware and document middleware.