在更新后中间件中发现不正确的文档修订号

Posted

技术标签:

【中文标题】在更新后中间件中发现不正确的文档修订号【英文标题】:Incorrect document revision number found in post update middleware 【发布时间】:2016-06-03 01:50:48 【问题描述】:

我有一个 Mongoose 插件,我用它来增加文档修订号 (__v),以及创建修订本身。该插件涵盖了 Documents Doc.save() 中间件功能,以及 Query updatefindOneAndUpdate 中间件功能。

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

所以这主要按预期工作。对于文档和查询交互,文档的__v 值都会增加,并且还会创建修订文档。我坚持的部分与查询中间件函数updatefindOneAndUpdate 有关。尽管 __v 通过 pre 事件在文档中更新,但 post 事件中的 this.__v 值似乎没有看到更新的值。这意味着修订被创建并引用了文档的错误修订号。

这真是太奇怪了,因为文档__v确实当我在数据库中查看它时实际上得到了更新,但是当我 console.log this.__vin post update.. 它会在更新之前看到修订号..

对于临时修复,我只是手动增加它,如果它是一个查询 MW 函数:

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

但显然,这只是一个创可贴,所以如果有真正的解决方法,那就太好了

有什么想法吗?

【问题讨论】:

【参考方案1】:

即使 __v 通过 pre 事件在文档中更新,但 post 事件中的 this.__v 值似乎没有看到更新后的值。

这很可能是因为您的 updatefindOneAndUpdate 的中间件没有使用异步回调来等待操作完成后再继续(您确实为 @987654326 实现了@中间件)。

所以让它使用回调:

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

【讨论】:

哦……我真的想知道为什么它没有next,我实际上是从this answer 那里得到的,我想我应该进一步研究它。 . 谢谢! 我注意到 Mongoose 文档中提到的示例中的相同(缺少回调),尽管它正在更新可能不会在后续查询/中间件中使用的字段。我想作者出于简洁的原因省略了回调(不一定是个好主意,因为它会混淆人们)。

以上是关于在更新后中间件中发现不正确的文档修订号的主要内容,如果未能解决你的问题,请参考以下文章

在 SVN 中添加带有修订号的文件

如何在每次提交后自动保存 SVN 修订号?

如何在猫鼬发布更新中间件期间访问更新的文档?

为任何更新查询增加 Mongoose 文档版本的简单方法?

SetTimeout 在 Mongoose 模式后中间件中不起作用

淘宝中间件——tair(下)