【问题标题】:mongoose get db value in pre-save hook猫鼬在预保存钩子中获取数据库值
【发布时间】:2013-08-14 02:35:08
【问题描述】:

我想知道在这样的预保存猫鼬钩子中脏道具的“干净”值是什么:

UserSchema.pre('save', function(next) {
    var user = this;

    if (user.isModified('password')){
       //i want to know what the value of user.password was before it was changed
    }
    next()
}

是否可以在不查找数据库的情况下查找旧值?

【问题讨论】:

    标签: node.js mongoose


    【解决方案1】:

    默认情况下,不存储旧值。您必须做的是使用 post init 挂钩(猫鼬功能)跟踪旧数据。

    我们所做的是将原始文档的副本附加到从 MongoDB 中提取的所有项目中。我们为每个需要获取预脏数据以进行比较的模式提供了以下代码:

    schema.post( 'init', function() {
        this._original = this.toObject();
    } );
    

    NodeJS 非常高效,并且在可能的情况下会在写入时进行复制,因此除非您修改整个文档,否则您不会看到双倍的内存消耗。只有这样 _original 才会真正消耗双倍的内存。

    【讨论】:

      【解决方案2】:

      因此,在预保存挂钩中,从阅读this section of the source code 可以看出,我认为之前的值不会存储在任何地方。因此,您必须从 mongodb 加载文档才能获取它。

      但是,您可能希望使用virtuals 机制而不是预保存挂钩来存储旧值,然后再将其更改为新值。

      var virtual = schema.virtual('password');
      virtual.set(function (v) {
        var this._oldPassword = this.password;
        return v;
      });
      

      用这些方法做一些实验,看看你是否能让一些东西合适地工作。

      【讨论】:

      • 你为什么建议我使用virtual vs path
      • 因为path 只定义了数据属性的名称和类型,而virtual 允许您定义通过get/set 方法访问的属性,您可以在其中放置代码。
      • @PeterLyons 很抱歉复活了旧线程,但是我认为如果在负载均衡器后面部署了多个节点服务器,这种方法将不起作用,对吧?
      • @saurabh 我认为它应该可以正常工作,因为单个请求始终在单个节点实例上执行。因此,this._oldPassword 不会在定义和用法之间发生变化。如果您需要一个最新的值并且值可能会被其他请求更改,它就会失败。但无论如何,这种情况要复杂得多。
      • @Saurabh:为什么要为提出相关问题道歉?时间流逝与它有什么关系?
      猜你喜欢
      • 1970-01-01
      • 2018-03-04
      • 1970-01-01
      • 2012-08-08
      • 1970-01-01
      • 1970-01-01
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多