使用 Mongoose 时需要避免的陷阱

阅读时长 6 分钟读完

Mongoose 是一个 Node.js 中非常流行的 MongoDB ODM(Object Data Modeling,对象数据映射)库,它可以轻松地对 MongoDB 进行操作。然而,在使用 Mongoose 时,有一些需要注意的陷阱,本文将为你详细介绍这些陷阱以及如何避免它们。

1. 避免混淆同名集合

在 Mongoose 中,每个 model 与一个 MongoDB 集合相对应,并且默认情况下,集合的名称是 model 名称的复数形式。例如,一个名为 User 的 model 对应于一个名为 users 的集合。如果你采用了下面的方式来创建 model:

其中第三个参数指定集合的名称为 users,它与 model 名称一致,这就容易造成混淆。为避免这种情况,建议统一使用集合名称的复数形式(即不指定第三个参数),这样就不会发生混淆。

2. 关闭自动重连

Mongoose 默认情况下会进行自动重连,即在 MongoDB 数据库故障时自动尝试重新连接。但这可能会导致一些问题,例如,如果你自己手动关闭了数据库,Mongoose 会不停地尝试重连,这会浪费大量资源。

为了避免这种情况,可以在连接数据库时添加一个选项:

这样就可以避免自动重连了。当然,如果你需要自动重连,则可以将这个选项改为 true

3. 使用 schema 的 type 属性

在 Mongoose 中,schema 是定义 model 的核心部分。在定义 schema 时,我们通常会使用下面的方式:

这样就定义了一个包含三个属性的 schema。然而,上面的例子中,我们没有为每个属性指定 type 属性。这是因为,当我们没有指定 type 时,Mongoose 会根据属性值的类型自动推断属性的类型。

例如,上面的 nameemail 属性都是字符串类型,因此 Mongoose 会把它们的 type 自动设为 String。然而,如果你使用了类似下面的方式:

虽然这样指定 type 属性不会造成什么问题,但这样做肯定有些繁琐。因此,在定义 schema 时不必指定 type 属性,这可以令代码更加简洁。

4. 避免混淆 model 和 document

在 Mongoose 中,model 和 document 是两个不同的概念。model 是 Mongoose 的核心部分,它代表一个 MongoDB 集合,并且负责定义 schema、创建 document、进行查询等操作。document 则代表集合中的一个实例,它由一个 model 创建而来,可以被直接操作、读取和修改。

因此,在使用 Mongoose 时,需要时刻注意两者的区别。例如,应该将 model 名称用 Model 结尾,而将 document 名称用 Document 结尾,这样可以更易于区分。同时,也不要忘记每个 document 的 _id 属性,它是 MongoDB 中每个 document 的唯一标识。

5. 使用 Promise

Mongoose 的很多操作都是异步的,例如连接数据库、删除数据、查询数据等等。通常情况下,我们可以使用回调函数来处理这些异步操作,例如:

然而,使用回调函数可能会导致回调地狱,代码难以维护。因此,在 Mongoose 中,使用 Promise 更加方便。例如,你可以把上面的代码重写成:

当然,使用 Promise 也需要注意一些细节,例如,需要确保同时使用 resolve()reject()

6. 不要使用 save 方法

在 Mongoose 中,你可以使用 save 方法来保存一个 document。例如:

然而,使用 save 方法可能会导致一些问题,例如:

  • 它会自动将所有属性进行保存,即使这些属性没有变化也会覆盖存在的数据。
  • 它是一个异步操作,性能不高。
  • 如果需要更新一个 document,必须先查询这个 document,然后将新的值传递给这个 document 并调用它的 save 方法,这会增加代码难度和复杂度。

因此,在大多数情况下,推荐使用 updateOneupdateMany 方法来更新一个 document,例如:

总结

在使用 Mongoose 时,需要注意避免上述的陷阱和问题。为了确保代码的可读性和维护性,建议在定义 schema 时不必指定每个属性的 type,而应该统一使用集合名称的复数形式,同时使用 Promise 对异步操作进行处理。另外,不要使用 save 方法,而应该使用 updateOneupdateMany 方法来更新 document。通过避免这些问题,你可以更加高效地使用 Mongoose,从而更好地完成前端开发工作。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6492728548841e98940420af

纠错
反馈