当前位置: 首页 > 面试题库 >

猫鼬upsert操作是否会更新/更新默认架构值?

王锐
2023-03-14
问题内容

猫鼬架构:

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

Upsert操作:

const upsertDoc = {
...
}

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

当我UPSERT
updatefindOneAndUpdate默认模式值createDateupdateDate总是更新不管文档插入或更新。使用时是相同的$set(当然,我不传递日期)。

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


问题答案:

如果您正在寻找预期行为的“证明”,那么除了源代码本身之外,别无所求。特别是在schema.js主要定义内:

        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字段,或您在模式选项中映射到该键的任何名称。

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

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

作为参考,整个主要功能(schema.js目前在其中列出了该功能的适用范围)始于第798行,该genUpdates()功能在此处显示的列表的底部部分中被调用,但顶部是该功能的最后几行,其中的$setOnInsertget
键定义。

因此,在总结,是每一个“更新”的动作是故意的updatedAt映射领域已经电流Date值分配,并且也认为,“更新”被修改为包括$setOnInsert其行动
只有 当一个新的文档作为的结果创建适用“ upsert”操作createdAt



 类似资料:
  • 问题内容: 我已经查看了网站上的一些问题,但还没有弄清楚我在做什么错。我有一些这样的代码: 我不确定在中间应该做什么以使其正确更新数据库。我已经尝试了很多东西,但是无法撤消以找出所有我尝试过的东西。我一整夜都花了时间,我希望它能正常工作。 这几乎是我想要的,我想知道是否有任何方法可以在条件部分 我会继续玩弄它。 问题答案: 这正是我想要的,只有一行。:D完美!

  • 可写CTE被认为是9.5之前UPSERT的一种解决方案,如在PostgreSQL中重复更新时插入所述? 可以使用以下可写CTEs惯用语执行UPSERT,其中包含的信息是作为更新还是插入结束的: 此查询将返回“更新”或“插入”,或者可能(很少)失败,违反了https://dba.stackexchange.com/questions/78510/why-is-cte-open-to-lost-upd

  • 问题内容: 我有一个让我感到困惑的奇怪问题。我有一个模型: 变体条目如下所示: 我需要添加一个新字段-说“颜色”。所以我这样做是为了批量更新: 但是,“颜色”字段未设置-如果我再次浏览并注释掉该行,则它不会显示。我似乎无法弄清楚为什么要这样做。我有一个onSave事件,该事件已正确触发,因此可以保存。我也没有对版本结构进行任何检查- 即没有代码只允许代码和价格。我显然缺少了一些东西,但几个小时后我

  • 问题内容: 我的文件 夹Folder 具有以下架构: 因此,对于每个页面,我可以拥有许多权限。在CMS中,有一个面板,其中列出了所有文件夹及其权限。管理员可以编辑一个权限并保存。 我可以很容易地用其权限数组保存整个 Folder 文档,其中只修改了一个权限。但是我不想保存所有文档(实际架构中包含更多字段),所以我这样做了: 但是问题是 烫发 总是 不确定的 !我试图以这种方式“静态地”获取许可:

  • 问题内容: 我有一个典型的架构和模型: 当我执行此更新时,它仅在定义回调时才有效,否则仅执行但数据库中的值未更改: 这有效: 这是一个错误吗?我没有在文档中看到是否需要回调,但是要求这样做很奇怪……我认为我在这里缺少了一些东西。 注意:我通过电子邮件匹配以测试建议,我在NodeJS v0.8.17中使用猫鼬v3.5.4,并具有简单的Express v3.0.6设置。 提前致谢。 问题答案: 用猫鼬

  • 使用下面的代码,我尝试创建一个新的项模式并将其推入第一个集合对象。我使用findById函数传递要更新的集合对象的_id。找到带有我的id的集合后,我只需将一个项模式推入集合对象的items数组。我得到Res.Status(200),但我的items数组从未更新。还有人有这个问题吗?谢谢你的帮助。