在保存和保存后保存Mongoose中间件方法之间的数据

Jus*_*tin 13 javascript mongoose mongodb node.js mongoose-schema

查看更新示例代码@BOTTOM

我在我的当前项目的NodeJS利用猫鼬(这是真棒顺便说一句!),我有一个MDB集合多数民众赞成要存储的文件在不同的集合的变化(基本上是一个更新日志存储了什么修改)

我如何努力实现这一点是创建一个存储文档的JSON版本的函数,这是通过pre('save')钩子完成的.然后创建另一个钩子,通过它执行post('save'),比较存储的数据pre('save'),并将其与文档新数据进行比较.

这是我到目前为止所拥有的:

var origDocument 
var testVar = 'Goodbye World'

module.exports = ( schema, options ) => {
    schema.pre( 'save', function( next ) {
        // Store the original value of the documents attrCache.Description value
        origDocument = this.toJSON().attrCache.Description

        // Change the testVar value to see if the change is reflected in post(save)
        testVar = 'Hello World'
        next()
    } )

    schema.post( 'save', function(  ) {
        // Attempt to compare the documents previous value of attrCache.Description, with the new value
        console.log("BEFORE:", origDocument)
        console.log("AFTER:", this.toJSON().attrCache.Description)

        // Both of the above values are the same! >.<

        console.log('post(save):',testVar) // result: post(save):Hello World
        // But the above works just fine..
    } )
}
Run Code Online (Sandbox Code Playgroud)

我原本不认为这会起作用.要测试两个钩得到在同一范围内执行时,我在称为页的顶部创建了一个测试变量testVar与某个任意值,然后在post(save)钩,检索到的testVar,并且该变量的值修改被认为在后保存钩子.

所以,从那里,我只是将值存储this.toJSON()在一个变量中,然后在post(保存)钩子中,我试图检索该文档的缓存版本,并将其与之进行比较this.toJSON().但是,它看起来并不像来自未pre(save)保存预修改数据的文档,它在更新以某种方式具有文档的价值.

那么为什么我可以testVarpre(save)钩子中更新from 的值,并且这个更改反映在post(save)钩子函数中,但我不能对文档本身做同样的事情?

我试图在这里做什么甚至可能吗?如果是这样,我做错了什么?如果不是 - 我怎么能做到这一点?

谢谢

更新

根据@Avraam的建议,我尝试运行数据,然后JSON.stringify()通过pre(save)钩子将其保存在内存中,然后执行相同操作post(save),如下所示:

var origDocument 

module.exports = ( schema, options ) => {
    schema.pre( 'save', function( next ) {

        origDocument = JSON.stringify( this.toJSON().attributes[1].value )

        // Should store and output the CURRENT value as it was before the 
        // document update... but it displays the NEW value somehow
        console.log( '[MIDDLEWARE] ORIGINAL value:', origDocument )

        next()
    } )

    schema.post( 'save', function(  ) {
        var newDocument = JSON.stringify(this.toJSON().attributes[1].value)

        console.log( '[MIDDLEWARE] UPDATED value:', newDocument )
    } )
}
Run Code Online (Sandbox Code Playgroud)

这是更新mongoose文档的脚本:

Asset.getAsset( '56d0819b655baf4a4a7f9cad' )
    .then( assetDoc => {
        // Display original value of attribute
        console.log('[QUERY] ORIGINAL value:', assetDoc.attributes[1].value)

        var updateNum = parseInt( assetDoc.__v )+1
        assetDoc.attr('Description').set('Revision: ' + updateNum )

        return assetDoc.save()
    } )
    .then(data => {
        // Display the new value of the attribute
        console.log('[QUERY] UPDATED value:', data.attributes[1].value)
        //console.log('DONE')
    })
    .catch( err => console.error( 'ERROR:',err ) )
Run Code Online (Sandbox Code Playgroud)

当我运行New脚本时继承控制台输出:

[QUERY] ORIGINAL value: Revision: 67
[MIDDLEWARE] ORIGINAL value: "Revision: 68"
[MIDDLEWARE] UPDATED value: "Revision: 68"
[QUERY] UPDATED value: Revision: 68
Run Code Online (Sandbox Code Playgroud)

如您所见,[QUERY] ORIGINAL值和[QUERY] UPDATED值显示有更新.但[MIDDLEWARE]的原始/更新值仍然相同......所以我仍然坚持原因

UPDATE

我想也许我可以提供一个更简化但更详细的例子.

下面是中间件模块,它应该比较pre(save)

post(save):'使用严格'

import _ from 'moar-lodash'
import * as appRoot from 'app-root-path'
import Mongoose from 'mongoose'
import diff from 'deep-diff'

var originalDesc 


module.exports = ( schema, options ) => {
    schema.pre( 'save', function( next ) {
        originalDesc =  JSON.parse( JSON.stringify( this.toJSON() ) ).attributes[1].value

        console.log( '[MIDDLEWARE ORIGINAL Desc]\n\t', originalDesc )
        next()
    } )

    schema.post( 'save', function(  ) {
        var newDesc =  JSON.parse( JSON.stringify( this.toJSON() ) ).attributes[1].value

        console.log( '[MIDDLEWARE NEW Desc]\n\t', newDesc)
    } )
}
Run Code Online (Sandbox Code Playgroud)

接下来是使用Asset模型的代码并更新Description属性...

'use strict'

import _ from 'moar-lodash'
import Promise from 'bluebird'
import Mongoose from 'mongoose'
import Async from 'async'
import Util from 'util'
import * as appRoot from 'app-root-path'

Mongoose.Promise = Promise

Mongoose.connect( appRoot.require('./dist/lib/config').database.connection )

const accountLib = appRoot.require('./dist/lib/account')

const models = require( '../models' )( Mongoose )

models.Asset.getAsset( '56d0819b655baf4a4a7f9cad' )
    .then( assetDoc => {
        var jqDoc = JSON.parse(JSON.stringify(assetDoc.toJSON()))

        // Show the CURRENT description
        console.log('[IN QUERY - Before Modify]\n\t', jqDoc.attributes[1].value)

        assetDoc.attr('Description').set( 'Date-'+Date.now() )

        return assetDoc.save()

    } )
    .then(data => {
        // Just show the Description AFTER it was saved
        console.log('[AFTER QUERY - AFTER Modify]\n\t', data.attributes[1].value)
    })
    .catch( err => console.error( 'ERROR:',err ) )
    .finally( () => {
        Mongoose.connection.close()
        console.log('# Connection Closed')
    })


[IN QUERY - Before Modify]
     Date-1474915946697
[MIDDLEWARE ORIGINAL Desc]
     Date-1474916372134
[MIDDLEWARE NEW Desc]
     Date-1474916372134
[AFTER QUERY - AFTER Modify]
     Date-1474916372134
# Connection Closed
Run Code Online (Sandbox Code Playgroud)

Avr*_*dis 0

具有origDocument对 的引用,this.toJSON()并且当您调用console.log实际对象的值时,参考点已经发生了更改。使用诸如JSON.stringify比较值之类的东西。

origDocument = JSON.stringify( this.toJSON() )