猫鼬upsert操作是否会更新/更新默认架构值? [英] Does Mongoose upsert operation update/renew default schema values?

查看:31
本文介绍了猫鼬upsert操作是否会更新/更新默认架构值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

猫鼬模式:

new Schema({
    ...
    createDate: { type: Date, default: Date.now },
    updateDate: { type: Date, default: Date.now }
});

Upsert操作:

const upsertDoc = {
...
}

Model.update({ key: 123 }, upsertDoc, { upsert: true })

当我使用updatefindOneAndUpdate向上插入时,无论插入或更新文档,默认方案值createDateupdateDate总是会更新.使用$set时是相同的(当然,我不传递日期).

when I upsert with update or findOneAndUpdate the default schema values createDate and updateDate are always renewed no matter document is inserted or updated. It's same when I use $set (in which of course I don't pass dates).

我似乎没有发现任何东西可以判断这是否是预期的行为.我希望日期仅在插入时添加,而不更新,除非明确设置.

I don't seem to find anything to tell if it's an expected behavior. I expect dates to be added only on insert and not update, unless explicitly set.

推荐答案

如果您正在寻找预期行为的证明",那么除了源代码本身外,别无其他.特别是在 schema.js主要定义 :

If you are looking for "proof" of the expected behavior, then look no further than the source code itself. Particularly within the schema.js main definition:

        updates.$setOnInsert = {};
        updates.$setOnInsert[createdAt] = now;
      }

      return updates;
    };

    this.methods.initializeTimestamps = function() {
      if (createdAt && !this.get(createdAt)) {
        this.set(createdAt, new Date());
      }
      if (updatedAt && !this.get(updatedAt)) {
        this.set(updatedAt, new Date());
      }
      return this;
    };

    this.pre('findOneAndUpdate', _setTimestampsOnUpdate);
    this.pre('update', _setTimestampsOnUpdate);
    this.pre('updateOne', _setTimestampsOnUpdate);
    this.pre('updateMany', _setTimestampsOnUpdate);
  }

  function _setTimestampsOnUpdate(next) {
    var overwrite = this.options.overwrite;
    this.update({}, genUpdates(this.getUpdate(), overwrite), {
      overwrite: overwrite
    });
    applyTimestampsToChildren(this);
    next();
  }

因此,您可以看到所有'pre'中间件处理程序都已为每个"update"方法变量和相同的功能代码注册.这些实质上都会在任何更新"中修改 $set 运算符",您发出的要求包括updatedAt字段,或者您在架构选项中映射到该键的任何名称.

So there you can see all the 'pre' middleware handlers being registered for each of the "update" method variants and to the same functional code. These all essentially modify the $set operator in any "update" you issue to include the updatedAt field, or whatever name you mapped to that key in the schema options.

通过"upsert"操作发送的实际语句使用 $setOnInsert 作为createdAt字段或映射的选项名称(请参见清单顶部).此操作仅在实际发生更新"时适用,因此该值实际上不会触及到从不存在且仅与任何更新"方法匹配的文档.

The actual statement sent with "upsert" actions uses $setOnInsert for the createdAt field or mapped option name ( see the top of the listing ). This action only applies when an "upsert" actually occurs, so documents that exist and are merely matches for any of the "update" methods are never actually touched by this value.

这些运算符是MongoDB工作方式的一部分,与Mongoose无关,但此处显示的代码显示了Mongoose如何调整"您的"update"操作以包括这些附加操作.

Those operators are part of how MongoDB works and not really to do with mongoose, but the code shown here shows how mongoose "adjusts" your "update" actions in order to include these additional operations.

schema.js中的整个主要功能供参考,目前可以确定要应用的内容从行号#798 用于genUpdates()函数,如清单所示底部所示,而顶部是该函数的最后几行,其中 $setOnInsert 得到定义.

For reference the whole main function in schema.js which works out what to apply currently begins at Line #798 for the genUpdates() function as called in the bottom part of the listing shown here yet the top part is the last few lines of that function where the keys of $setOnInsert get defined.

因此,总而言之,每个更新"操作都是是",这是有意为updatedAt映射的字段分配了当前的Date值,并且还对更新"进行了修改以包括

So in summary, YES every "update" action is intentional that the updatedAt mapped field has the current Date value assigned, and also that the "updates" are modified to include the $setOnInsert action which only applies when a new document is created as the result of an "upsert" action for the createdAt mapped field.

这篇关于猫鼬upsert操作是否会更新/更新默认架构值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆