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

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

问题描述

猫鼬架构:

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

插入操作:

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 中.> 主要定义:

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' 中间件处理程序正在为每个更新"方法变体和相同的功能代码注册.这些基本上都修改了$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 如何调整"您的更新"操作以包含这些附加操作.

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 值,并且更新"也被修改包括 $setOnInsert 操作这适用于作为 createdAt 映射字段的更新插入"操作的结果创建新文档时.

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.

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

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