解决 Mongoose 指定默认值后无法更新的问题

背景

在前端开发过程中,常常需要使用到 MongoDB 数据库。而在 Node.js 中,最常用的 MongoDB 驱动是 Mongoose。在使用 Mongoose 的过程中,我们经常会遇到一些问题,其中一个比较常见的问题就是,当我们指定了默认值后,无法在更新文档时正确地更新相关字段。

问题

我们在使用 Mongoose 插入文档时,可以设置默认值,例如:

----- ---------- - --- -----------------
    ----- - ----- ------- -------- ---- ----- --
    ---- - ----- ------- -------- -- --
---

在上面的代码中,我们为 nameage 两个字段设置了默认值,其中 name 的默认值为 'New User'age 的默认值为 18。当我们插入一条新的用户记录时,如果没有设置 nameage,那么 Mongoose 会自动将其设为默认值。

例如,我们插入一条记录:

----- ---- - --- ------ ----- ------ ---
----- ------------

由于我们只设置了 name,而没有设置 age,因此在插入记录时,age 的值将被自动设为 18,因为这是我们在定义 schema 时设置的默认值。

但是,如果我们尝试更新这个记录,例如将 age 的值改为 20,我们会发现更新并没有生效:

----- ---------------- ----- ------ -- - ---- -- ---

通过上面的代码,我们本来希望将 age 的值从 18 修改为 20,但实际上数据库中该记录的 age 字段仍然为 18,没有发生变化。

原因

这是因为 Mongoose 在执行更新操作时,默认情况下会跳过默认值。也就是说,即使我们在更新操作中明确地指定了某个字段的值,如果该字段在定义 schema 时有默认值,Mongoose 也不会将更新后的值保存到数据库中。

解决方法

要解决这个问题,我们需要手动对默认值进行覆盖。具体来说,我们可以使用 lean() 方法获取纯 JavaScript 对象(plain JavaScript object),然后手动合并更新操作中的值和默认值,最后将合并后的值保存回数据库中。

下面是示例代码:

----- ------- - ----- -------------- ----- ------ ----------
----- ----------- - ------------ -------- - ---- -- ---
----- ------ - ----- ---------------- ----- ------ -- -------------

上面的代码中,我们使用了 Lodash 库的 assign() 方法来合并默认值和更新值。首先,我们通过 findOne() 方法获取符合条件的单个文档,然后使用 lean() 方法将其转换为纯 JavaScript 对象。接着,我们使用 assign() 方法将更新操作中的新值合并到旧的文档对象中,最后使用 updateOne() 方法将合并后的文档保存回数据库中。

值得注意的是,由于 lean() 方法返回的是纯 JavaScript 对象,因此需要手动调用 save() 方法将更新后的值保存回数据库中。如果我们不使用 lean() 方法,直接调用 updateOne() 方法,虽然会返回更新操作的结果,但是数据库中的值却不会发生变化。

总结

在使用 Mongoose 进行 MongoDB 开发时,如果定义了默认值,并且在进行更新操作时发现无法更新一些字段,我们应该手动对默认值进行覆盖,以确保更新操作能够生效。同时,我们需要注意,当使用 lean() 方法获取纯 JavaScript 对象后,必须手动调用 save() 方法才能将更新后的值保存回数据库中。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/653ce5c47d4982a6eb6d9b90


猜你喜欢

  • 从 jQuery 到 React-Native,我从 web 逃离

    从 jQuery 到 React-Native,我从 web 逃离 Web 前端一直是我一直非常热爱的技术领域,并且一直都坚定地相信它的未来非常光明。然而,最近我开始质疑这一点,并且开始尝试一些新的东...

    1 年前
  • 如何使用 ES11 中的 Array.prototype.fill() 快速填充数组

    ES11 中新增了 Array.prototype.fill() 方法,它可以有效地填充数组,使用起来非常简便。在本文中,我们将学习如何使用 Array.prototype.fill() 方法,并结合...

    1 年前
  • 使用 Jest、Enzyme、Jest-Mock 和 TypeScript 测试 React 组件

    在进行前端开发时,测试是不可或缺的一个环节。而 React 组件的测试,又是前端开发中的一个重要内容。本文将介绍如何使用 Jest、Enzyme、Jest-Mock 和 TypeScript 来测试 ...

    1 年前
  • 使用 ES7 的 Array.prototype.includes 方法检查数组中是否存在某个值

    前言 在前端开发中,经常需要检查一个数组中是否包含某个特定值。在过去,我们可能会使用 Array.prototype.indexOf 方法来完成这个任务。然而,这个方法并不是太方便使用,因为它返回的是...

    1 年前
  • CSS Flexbox 布局实现根据内容自适应宽度的方法

    在网页开发中,我们经常需要实现根据内容来自适应宽度的效果,比如导航栏、标签页、图片列表等等。传统的方案是使用浮动布局或者inline-block布局,但是这些方案都有一些缺点,比如浮动布局需要清除浮动...

    1 年前
  • Angular 中的表单验证与自定义表单验证

    表单是 Web 应用中最常见的交互方式之一。要保证表单数据的正确性和完整性,表单验证是不可避免的。Angular 提供了丰富的表单验证功能,包括内置的验证规则以及自定义的验证器。

    1 年前
  • Mocha 测试用例中的代码覆盖率

    Mocha 是一个流行的 JavaScript 测试框架,它被广泛用于前端和后端代码的单元测试和集成测试。测试代码的覆盖率是衡量测试质量的重要指标之一,它可以帮助我们发现代码中的潜在问题和漏洞。

    1 年前
  • LESS 中的递归 Mixin 技巧

    在前端开发中,我们经常需要处理大量的样式文件,而 CSS 的语法与结构本身并不便于维护和修改。LESS 是一种 CSS 预处理器,它在保留 CSS 基本语法的同时,提供了更加丰富、灵活的样式定义方式。

    1 年前
  • 解决 ESLint 和 Jest 测试框架的冲突问题

    介绍 ESLint 是前端开发中常用的静态代码检查工具,可以检查代码规范和潜在的错误。 Jest 是前端测试框架,可以用来编写和运行单元测试、集成测试等。 在使用 ESLint 和 Jest 时,可能...

    1 年前
  • Material Design 如何优化小程序

    前言 在前端开发领域,Material Design 是一个广为人知的设计体系及样式库。它让 Android 设计及其应用之间的转换更加无缝,并且可以在多个平台上实现一致的 UI 设计。

    1 年前
  • MongoDB 性能分析与优化

    MongoDB 是一种非常流行的 NoSQL 数据库,它以其高效、灵活和强大的数据存储能力而获得了广泛的应用。然而,在实际应用中,MongoDB 的性能问题也时常成为开发者们的烦恼。

    1 年前
  • Kubernetes-Service 之 Cluster IP

    在 Kubernetes 集群中,服务是一个抽象的概念,它用于将访问 Pod 的请求统一管理和路由。Kubernetes 的服务有四种类型,分别是: ClusterIP NodePort LoadB...

    1 年前
  • 如何使用 Cypress 进行断言测试

    Cypress 是一个流行的前端测试框架,它支持自动化断言测试和交互式测试。本文将介绍如何使用 Cypress 进行断言测试,包括使用 Cypress 的基本语法和最佳实践示例。

    1 年前
  • 如何使用 Fastify 实现 OAuth2.0 认证

    OAuth2.0 是目前广泛使用的授权协议,可用于保护 API 和 Web 应用程序的安全。本文将介绍如何使用 Fastify 实现 OAuth2.0 认证。 OAuth2.0 简介 OAuth2.0...

    1 年前
  • Custom Elements 在 Angular 中的应用

    在现代 web 开发中,组件化是一种基本的设计模式。Angular 是一个流行的前端框架,其组件系统让开发者可以自定义组件,并可以重复利用这些组件。在 Angular 中,我们可以通过 Custom ...

    1 年前
  • RxJS 中的 skip 操作符详解

    RxJS 是一个非常强大的响应式编程库,它提供了丰富的操作符来处理异步数据流,并且它的操作符可以组合在一起形成强大的数据处理链。 其中一个非常实用的操作符是 skip,skip 操作符可以将 obse...

    1 年前
  • SASS 样式表编译错误的解决方案

    随着 web 开发技术的不断更新,前端工程师们越来越注重编码效率和代码组织的规范性。而在样式表的编写方面,SASS 成为了前端开发中最实用的工具之一。SASS 是一种 CSS 预处理器,它通过扩展 C...

    1 年前
  • CSS Reset:消除浏览器内置样式的困扰

    当我们在开发网页时,经常会遇到一些浏览器内置样式的问题,这些样式会影响我们的设计效果,让我们的页面无法完全按照我们的预期呈现。不过,好在这些问题有相对简单而有效的解决方案,即所谓的 CSS Reset...

    1 年前
  • ES8 新增的对象静态方法 Object.values() 详解

    介绍 在 ES8 中,新增了许多对象静态方法,其中 Object.values() 就是其中之一。这个方法可以返回一个给定对象自身可枚举属性的值的数组(不包括原型链上的属性)。

    1 年前
  • ES9 中的新数据结构:Map 集合

    在 ES9 中,JavaScript 引入了一种新的数据结构:Map 集合。Map 是一种类似于对象的键值对集合,但也有一些不同之处。本文将介绍 Map 集合的概念、使用方法以及与对象的异同点,以及如...

    1 年前

相关推荐

    暂无文章