Mongoose 是 Node.js 中最流行的 MongoDB 对象模型工具之一,它提供了很多强大的功能,虚拟属性(virtuals)就是其中之一。
虚拟属性是一种与存储值无关的属性,它由计算得出,可以使用 getter 和 setter 来访问。在本文中,将会深入探讨 Mongoose 虚拟属性的 getter 和 setter 的使用,以及如何为您的应用程序提供便利的方法。
getter 和 setter 的基础知识
获取器(getter)和设置器(setter)是 JavaScript 对象的属性,用于访问和设置对象的值。在 Mongoose 中,您可以使用 getter 和 setter 来定义虚拟属性,也就是无法直接存储在数据库中的属性。
Getter 是一个函数,只有一个参数(该参数表示要获取的属性的名称),它的返回值被视为该属性的值。Setter 是一个函数,它接收两个参数(第一个参数是要设置的属性的名称,第二个参数是要给属性设置的值),它通常返回值为属性的值,但是不是必需的。
在 Mongoose 中定义 getter 和 setter
在 Mongoose 中,您可以使用 Schema.virtual() 方法定义虚拟属性,该方法接受两个参数:属性的名称和一个对象。该对象至少包含 getter 或 setter 中的一种。
此外,还必须将虚拟属性添加到您的 Schema definition 中允许它们在文档对象上使用。这可以使用 Schema.set() 方法中的对应参数来完成:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ------ - ---------------- ----- ---------- - --- -------- ------ ------- ----- ------ --- -------------------------------------------- - ------ ------------------ ---- --- -------------------------- - --------- ---- --- ------------------------ - --------- ---- --- ----- ---- - ---------------------- ------------
在此示例中,我们定义了一个虚拟属性 snippet,它使用 getter 和 slice() 方法返回 blog 文档对象的开头 50 个字符。我们还设置了 toObject 和 toJSON 选项,以便让 Mongoose 在将文档对象转换为普通 JS 对象或 JSON 字符串时包括虚拟属性。
如何使用 getter 和 setter
在上面的示例中,如果您要访问文档对象的 snippet 属性,则可以像访问普通属性一样访问它:
Blog.findOne({ ... }).then((blog) => { console.log(blog.snippet); });
您可以在示例中的 Blog 模型上定义任意数量的虚拟属性,只要您符合文档对象的对象模型的规则。Getter 和 setter 允许您为文档对象提供便利的方法,这些方法可以根据您的业务逻辑计算虚拟属性的值。
一些提示和技巧
如果您需要使用虚拟属性进行排序或过滤查询,那么请记住它们不能用作 Mongoose 查询和聚合管道的字段。
虚拟属性的内存使用和性能取决于它们的 getter 和 setter 实现。因此,如果您要计算计算量大的虚拟属性,请考虑使用正常属性存储并使用其自己的方法计算值,而不是虚拟属性。
如果您的虚拟属性包含填充查询,那么请记住对填充进行明智的处理,否则可能会降低性能。
练习
下面的示例演示了如何使用 setter 和 getter 进行身份验证,如果密码拦截则对密码加密,否则对密码不做更改。
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ------ - -------------------- ----- ------ - ---------------- ----- ---------- - --- -------- --------- ------- --------- ------ --- ------------------------------------ --------------- - -- ------------- - -- ----- --- --------------- ---- -- -- ----- - ------------- ------------- - ----- ------------------ ---- --- ---------------------- ----- ---------- - -- ----------------------------- - -- -- -------- ----------- -- ---------------------------------------------------------------- - ------------- - ----- -------------------------- ---- - - --- ----- ---- - ---------------------- ------------
在此示例中,我们使用 setter “pass” 自动对密码进行加密,并在保存之前使用 pre() 长钩子对密码进行额外的验证和 免重复加密。
结论
如您所见,使用 Mongoose 的虚拟属性可以提高应用程序的灵活性和可用性。getter 和 setter 允许表述属性来自代码而不是数据存储,得到计算的属性结果,并且让代码更简洁和易于维护。
我们希望您能够使用 getter 和 setter 来自定义您的项目中相关属性,让您的应用程序具有更多的补完计算和更高的可用性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/674eaff8e884a3e30f291f6d