请参阅底部更新的示例代码
我在当前的 NodeJS 项目中使用 Mongoose(顺便说一句,这非常棒!),并且我有一个 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..
} )
}
我原本不认为这会起作用。为了测试这两个钩子是否在同一范围内执行,我在页面顶部创建了一个测试变量,名为testVar
具有任意值,然后在post(save)
钩子,检索到testVar
,以及该变量的值修改was seen在帖子保存挂钩中。
所以从那里开始,我只是存储了this.toJSON()
在一个变量中,然后在 post(save) 挂钩中,我尝试检索该文档的缓存版本,并将其与this.toJSON()
。然而,它看起来并不像来自pre(save)
不保存预先修改的数据,它以某种方式具有文档的价值after它已更新。
那么为什么我可以更新的值testVar
从一个内pre(save)
钩子,并且该变化反映在post(save)
钩子函数,但我不能对文档本身做同样的事情?
我在这里尝试做的事情可能吗?如果是这样,我做错了什么?如果没有 - 我怎样才能做到这一点?
谢谢
Update
根据@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 )
} )
}
这是更新 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 ) )
这是我运行新脚本时的控制台输出:
[QUERY] ORIGINAL value: Revision: 67
[MIDDLEWARE] ORIGINAL value: "Revision: 68"
[MIDDLEWARE] UPDATED value: "Revision: 68"
[QUERY] UPDATED value: Revision: 68
如您所见,[查询] 原文值和[查询] 已更新值表明有更新。但是[中间件]原始/更新后的值仍然相同......所以我仍然不知道为什么
UPDATE
我想也许我可以提供一个更简化但更详细的示例。
这是应该比较的中间件模块pre(save)
and
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)
} )
}
然后这是使用的代码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