Mongoose 中文文档虚拟属性详解

在 MongoDB 的 Node.js 驱动 Mongoose 中,虚拟属性是一种模式属性,在对文档进行查询或者保存时会自动进行计算或者转换,但它不会在 MongoDB 中存储。这种特性在很多场景下非常有用,它可以给抽象属性和逻辑增加一个新的维度。

基本概念

在 Mongoose 中,虚拟属性的定义非常简单,我们可以通过在 Schema 中调用 virtual() 方法来声明一个虚拟属性。下面是一个示例:

可以看出,虚拟属性并不存储在 MongoDB 中,而是在运行时(取值时)计算得到。虚拟属性有两种类型:gettersetter,它们分别对应着一个属性值的读取和设置。

虚拟属性类型

Getter

Getter 是一个没有 setter 的虚拟属性类型。当我们在代码中访问该属性时,Mongoose 会执行 get 函数来获取该值。我们可以使用 get 函数返回计算过的值,也可以利用它进行一些复杂的运算、逻辑判断等处理。

下面的例子展示如何计算一个用户文档的年龄:

Getter 虚拟属性有一个非常重要的特性,它们可以通过虚拟属性计算,这对于需要频繁执行复杂计算的情况非常有用。而且 Getter 属性的计算可以依赖其他属性,方便我们进行维护和修改。

Setter

Setter 是一个没有 getter 的虚拟属性类型。当我们在代码中设置该属性时,Mongoose 会执行 set 函数,并返回一个新的属性值。Setter 有一个非常重要的作用,它可以用来将外部数据格式化为符合 Schema 规范的格式。

下面的例子展示了一个字符串去除空格的 setter:

这个 setter 可以用来格式化一个消息,也可以用来进行格式校验或转换。Setter 属性还有一个重要的应用场景,就是用来处理外部 API 或者用户输入的数据,保证数据都符合指定格式。

虚拟属性选项

ref

在 Mongoose 中,虚拟属性可以通过 ref 选项关联到其他文档,从而实现文档间关联。ref 选项用来指定被关联文档的 model,支持 string 形式和 objectid 形式。

下面的例子展示了如何在 Mongoose 中关联两个文档:

这个例子展示了如何通过虚拟属性 ref 将 Customer 和 Order 关联起来。我们使用 localFieldforeignField 选项分别指定了关联的本地字段和外部字段。这样,我们就可以在查询 Customer 时直接获取它的订单列表。

localField 和 foreignField

在 ref 选项中,我们使用了两个额外的选项:localFieldforeignField。它们描述了两个文档间关联的字段。

  • localField:用于指定本 model(即虚拟属性所属的 model)中用于与外部 model 进行关联的字段名称。默认值为 '_id'。

  • foreignField:用于指定与外部 model 关联的字段名称(即外部 model 中要关联的字段)。默认值为 '_id'。

在关联两个文档时,我们经常需要在查询时使用 populate() 方法,这个方法可以将虚拟属性关联的文档一并查询出来,从而避免了多次查询带来的性能损失。

总结

虚拟属性是 Mongoose 中非常有用的功能,它可以用来处理文档间的关联、逻辑计算和数据格式转换等问题。在使用虚拟属性时,需要特别注意一些选项(如 reflocalFieldforeignField),以及虚拟属性类型(如 getter 和 setter)的区别。同时,还需要充分理解虚拟属性的特性和使用场景,以便更好的利用它们。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653e69377d4982a6eb7e7b9c


纠错
反馈