Incorrect document revision number found in post u

2019-09-10 02:02发布

问题:

I have a Mongoose plugin which I use to increment the documents revision number (__v), as well as create revision itself. The plugin covers the Documents Doc.save() middleware function, as well as the Query update and findOneAndUpdate middleware functions.

module.exports = ( schema, options ) => {
    _.forEach( [ 'save','update', 'findOneAndUpdate' ], query => {
        // Since the Doc.save() middleware is the only document update middleware function, just isolate that one
        if( query === 'save' )
            schema.pre( query, function( next ) {
                this.increment()
                next()
            } )

        // The rest are query updates
        else
            schema.pre( query, function() {
                this.update( {}, { $inc: { __v: 1 } } )
            })


        // Create revisions for each document update
        schema.post( query, docData => {
            Mongoose.models.Revision.createRevision( {
                docsId: this._id,
                revision: docData.__v, // <-- This is the wrong number. It's one less than it should be
                document: { /* Stuff.. */ }
                // More stuff
            }, ( err, revision ) => {
                // CB Stuff
            })
        })
    })
}

So this mostly works as expected. The __v value of the document gets incremented for both document and query interactions, and the revision documents get created as well. The part that i'm stuck on, is related to the Query middleware functions, update and findOneAndUpdate. Even though the __v gets updated in the document via the pre event, the this.__v value in the post event doesn't seem to see the updated value. So that means the revision gets created and references the incorrect revision number of the document.

This is just super weird, because the documents __v does in fact get updated when I look at it in the database, but when I console.log the this.__vin the post update.. it sees the revision number prior to it being updated..

For a temporary fix, I just increment it manually, if its a query MW function:

schema.post( query, docData => {
    Mongoose.models.Revision.createRevision( {
        docsId: this._id,
        revision: ( query === 'save' // Temporary fix..
            ? docData.__v
            : docData.__v+1 ) // Add +1 if its a query function 
        document: { /* Stuff.. */ }
        // More stuff
    }, ( err, revision ) => {
        // CB Stuff
    })
})

But obviously, this is just a bandaid, so if theres a real fix for this, that would be great

Any idea?

回答1:

Even though the __v gets updated in the document via the pre event, the this.__v value in the post event doesn't seem to see the updated value.

That's most likely because your middleware for update and findOneAndUpdate isn't using an async callback to wait for the action to finish before continuing( something that you did implement for the save middleware).

So make it use the callback:

schema.pre( query, function(next) {
  this.update( {}, { $inc: { __v : 1 } }, next);
})