В промежуточном программном обеспечении после обновления обнаружен неверный номер версии документа.

У меня есть плагин Mongoose, который я использую для увеличения номера версии документа (__v), а также для создания самой версии. Плагин охватывает функцию промежуточного программного обеспечения Documents Doc.save(), а также функции промежуточного программного обеспечения Query update и findOneAndUpdate.

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 документа увеличивается как для взаимодействия с документом, так и для запроса, а также создаются документы редакции. Часть, на которой я застрял, связана с функциями промежуточного программного обеспечения Query, update и findOneAndUpdate. Несмотря на то, что __v обновляется в документе с помощью события pre, значение this.__v в событии post не видит обновленного значения. Это означает, что ревизия создается и ссылается на неправильный номер редакции документа.

Это очень странно, потому что документы __v на самом деле обновляются, когда я просматриваю их в базе данных, но когда я console.log, this.__vв 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
    })
})

Но очевидно, что это всего лишь пластырь, поэтому, если есть реальное решение для этого, это было бы здорово.

Есть идеи?


person Justin    schedule 21.02.2016    source источник


Ответы (1)


Несмотря на то, что __v обновляется в документе с помощью события pre, значение this.__v в событии post, похоже, не видит обновленного значения.

Скорее всего, это связано с тем, что ваше промежуточное ПО для update и findOneAndUpdate не использует асинхронный обратный вызов для ожидания завершения действия перед продолжением (то, что вы сделали для промежуточного ПО save).

Поэтому заставьте его использовать обратный вызов:

schema.pre( query, function(next) {
  this.update( {}, { $inc: { __v : 1 } }, next);
})
person robertklep    schedule 21.02.2016
comment
Ооо... Я действительно задавался вопросом, почему там не было next, я фактически взял его прямо из этот ответ, думаю, мне следовало изучить его подробнее.. Спасибо! - person Justin; 22.02.2016
comment
Я заметил то же самое (отсутствующий обратный вызов) в примере, упомянутом в документации Mongoose, хотя там обновлялось поле, которое, вероятно, не будет использоваться в последующих запросах/промежуточном программном обеспечении. Я предполагаю, что автор пропустил обратный вызов из соображений краткости (не обязательно хорошая идея, так как это может запутать людей). - person robertklep; 22.02.2016