Mongoose 中的预处理钩子详解及实际应用场景

阅读时长 7 分钟读完

Mongoose 是一种在 Node.js 平台上操作 MongoDB 数据库的工具,对于前端开发同样十分有用。Mongoose 提供了许多接口供我们对 MongoDB 进行操作,其中 Pre 钩子可以优化代码结构和提高开发效率。本文将详细探讨 Mongoose 中的预处理钩子,并提供实际应用场景和示例代码以供参考。

1. 什么是预处理钩子

预处理钩子顾名思义是在进行某个操作之前的钩子函数。Mongoose 中的预处理钩子分为两种: document 预处理钩子和 query 预处理钩子。

1.1 document 预处理钩子

document 预处理钩子作用于每一个文档对象实例,即一个 UserModel 的一条数据文档。它能够提前在固定的事件点上拦截文档生成的过程,对文档数据进行一些操作,最后再将修改后的文档数据存入数据库。

document 预处理钩子的应用场景举例:保存之前去重、日期更新、处理密码加密等。

1.2 query 预处理钩子

query 预处理钩子针对的是查询对象。它能够在查询对象执行 find、findOne、findOneAndUpdate、findOneAndDelete 等方法时,拦截查询请求,修改查询条件或者结果,最终返回处理后的结果。

query 预处理钩子的应用场景举例:权限控制、别名替换、正则表达式查询等。

2. document 预处理钩子

2.1 使用方式

在 Mongoose 中,document 预处理钩子是通过在 Schemma 上定义中间件来实现的。例如:

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

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

上面的代码定义了一个名为 userSchema 的 Schemma,并且定义了一个保存(save)的中间件。在执行 save 操作时,该中间件将被自动执行。

2.2 预处理钩子的执行顺序

预处理钩子有多个,Mongoose 对它们的执行顺序进行了规定。这些钩子分别是 validate、save、remove、init、findOneAndUpdate、findOneAndDelete,它们的执行顺序分别为:

  • init
  • validate
  • save
  • remove

其中,init 钩子会在 Schemma 被初始化时执行,validate 钩子是在执行 validate() 方法时执行,save 钩子是在执行 save() 方法时执行,remove 钩子是在执行 remove() 方法时执行。

2.3 预处理钩子参数及 next() 函数

预处理钩子函数接收一个函数作为参数,该函数被称为 next() 函数。next() 函数用于通知 Mongoose,中间件已经完成当前操作,可以执行下一个中间件或者结束整个操作。如果不执行 next() 函数,操作将一直处于等待状态。

3. query 预处理钩子

3.1 使用方式

使用 query 预处理钩子,需要在实际查询操作之前定义一个中间件。这里以查询所有用户为例:

上面的代码定义了一个查询中间件,在执行 find() 方法时将自动执行该中间件。

3.2 query 预处理钩子参数

Mongoose 中的 query 预处理钩子的参数与 document 预处理钩子的参数不同,它们包含以下几个参数:

4. 实际应用场景

4.1 document 预处理钩子应用场景

4.1.1 密码加密

用户密码在数据库中存储时,需要加密处理。预处理钩子可以在保存数据之前对密码进行加密处理。

4.1.2 生成 token

在开发中,生成 token 通常是在用户登录成功后保存在数据库中。可以使用预处理钩子,在文档保存之前为用户生成一个 token。

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

4.2 query 预处理钩子应用场景

4.2.1 别名替换

在 MongoDB 中,键名不能包含『.』符号,但有些情况下我们又必须使用它,如对于某个时间字段,我们可能需要使用『.』符号来体现其嵌套层级。这时可以使用别名替换来解决这个问题。

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

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

上面的代码将查询字段中的 『@createdAt』 替换成 MongoDB 所需的「createdAt」。

4.2.2 模糊查询

模糊查询通常需要使用正则表达式来实现。通过在预处理钩子中封装正则表达式,可以简化代码,提高效率。

上面的代码对查询条件中的名字进行模糊匹配,通过包装正则表达式,实现简化代码的目的。

5. 总结

通过本文我们了解了 Mongoose 中的预处理钩子,并使用统一的方法处理了文档和查询数据。而这些预处理钩子不仅可以优化代码结构,提高开发效率,还可以帮助我们解决实际问题,例如密码加密、Token 自动生成、别名替换、模糊查询等场景。

(完)

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

纠错
反馈