Skip to content

Access document in pre hook query middleware #8218

Closed

Description

@BenjErgizerBunny

Do you want to request a feature or report a bug?

Documentation Issue

What is the current behavior?

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?

#7497

Activity

  1. BenSower commented on Oct 7, 2019

    @BenSower

    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.

  2. vkarpov15 commented on Oct 9, 2019

    @vkarpov15
    Collaborator

    @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

  3. added
    docsThis issue is due to a mistake or omission in the mongoosejs.com documentation
    on Oct 9, 2019
  4. added this to the 5.7.5 milestone on Oct 9, 2019
  5. miadabdi commented on Sep 14, 2020

    @miadabdi

    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().

    schema.pre('updateOne', { document: true, query: false }, function() {
      console.log('Updating');
    });
    const Model = mongoose.model('Test', schema);
    
    const doc = new Model();
    await doc.updateOne({ $set: { name: 'test' } }); // Prints "Updating"
    
    // Doesn't print "Updating", because `Query#updateOne()` doesn't fire
    // document middleware.
    await Model.updateOne({}, { $set: { name: 'test' } });
    
  6. vkarpov15 commented on Sep 19, 2020

    @vkarpov15
    Collaborator

    @MichaelMikeJones I opened up #9434 to fix that 👍

  7. locked and limited conversation to collaborators on Sep 19, 2020
  8. vkarpov15 commented on Sep 22, 2020

    @vkarpov15
    Collaborator

    Actually @MichaelMikeJones the docs describe the behavior correctly, they mention the difference between pre('updateOne') query middleware and document middleware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsThis issue is due to a mistake or omission in the mongoosejs.com documentation

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions