如何优化 Mongoose 的 populate 查询性能?

阅读时长 7 分钟读完

在使用 Mongoose 进行 MongoDB 数据库操作时,我们难免会使用到 populate 方法来进行关联表查询。然而,由于数据库查询性能较低,过多的 populate 操作会严重影响程序性能。本文将介绍几种优化 Mongoose 的 populate 查询性能的方法,从而提高系统的性能。

1. 使用 Mongoose 自带的缓存机制

Mongoose 自带缓存机制可以自动缓存最后一次查询结果。在一定的情况下,可以减少查询数据库的次数。

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

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

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

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

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

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

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

2. 使用 Lean() 方法

Mongoose 中 populate 方法查询时默认返回的是 Mongoose Model 实例,但是如果只是单纯地取出关联文档中的数据,不需要对它进行任何的操作,我们可以使用lean()方法将返回的结果转换为普通 JavaScript 对象,从而避免了实例化的过程,提高程序性能。

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

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

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

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

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

3. 使用 pipeline 强化查询

查询时如果有多个 $lookup 查询操作,Mongoose 需要分发多个查询到 MongoDB 进行结果集合的组装,如果有多个 $lookup 查询,则需要分配多个查询到数据库集合。在用 Lean() 方法转化为普通对象或数组,这种方式显然会带来很大的查询性能损耗。

可以使用 pipeline 强化查询,通过 $lookup 将多个集合进行连接查询后返回结果。

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

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

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

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

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

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

-------

4. 大规模数据优化

如果你需要处理的数据集太大,无法通过 Mongoose 的缓存机制和 Lean() 方法来优化查询性能,可以尝试以下方法提高查询效率:

1. 使用只包含对象 ID 的文档

这种方式通常应用于只需要获取文档的 ID 的场景,例如在搜索记录中返回 ID 是否存在,如果存在,则根据 ID 加载其详细信息。

2. 使用分页功能

分页是一种有效的方式来降低查询负载,您可以通过以下方式使用分页:

这里我们设置页面大小为 10,要查询的页数为 5。首先,使用 limit() 方法限制结果集的大小。然后,使用skip() 方法跳过其它分页结果。接下来,使用sort() 方法指定以创建时间为准对结果集进行排序。最后,使用populate() 加载关联表数据。

3. 使用 MongoDB 的索引

索引是一种数据库结构,可以人为地指定字段或组合字段的值,使其能够更快地进行搜索。使用索引可以提高查询速度,从而提高数据库的性能。

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

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

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

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

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

在这个例子中,我们添加了索引到name字段。这个字段在User模型中使用。通过这种方式,查询将更快,应用程序性能将得到提高。

总结:

延迟加载是现代应用程序中非常重要的优化。用得好延迟加载可以减少不必要的性能问题,并使你的程序性能达到新的高度。虽然并不可能在所有情况下都使用延迟加载来进行数据库优化,但是,上述优化方式可以极大地提高程序的性能,使得程序能够更好地处理大量的数据。

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

纠错
反馈