在开发 Web 应用程序时,Mongoose 是一个非常强大的工具,它是一个通过 Node.js 操作 MongoDB 的工具。MongoDB 是一个文档数据库,而 Mongoose 将这些文档转换为 JavaScript 对象,这使得在应用程序中使用它们更加容易。其中的一个方面是虚拟属性和虚拟参考字段的使用,我们将在本文中探讨这些内容。
虚拟属性
虚拟属性是一些在模型中定义的属性,它们并不会存储在基础 MongoDB 数据库中,而是可以根据其他属性计算。虚拟属性有两种类型:计算属性和 Setter。
计算属性
计算属性是基于其他属性计算得到的属性。例如,考虑以下模型:
const UserSchema = new mongoose.Schema({ firstName: String, lastName: String }); const User = mongoose.model('User', UserSchema);
在这个模型中,我们可以定义一个虚拟属性 fullName
,它将 firstName
和 lastName
组合成一个完整的名称:
UserSchema.virtual('fullName').get(function() { return this.firstName + ' ' + this.lastName; });
在上面的代码中,我们通过 virtual()
方法定义了一个虚拟属性 fullName
,它使用一个 getter 函数,该函数返回 firstName
和 lastName
的组合字符串。
现在,我们可以像访问普通属性一样访问 fullName
属性,即使它不在数据库中:
const user = new User({ firstName: 'John', lastName: 'Doe' }); console.log(user.fullName); // 输出:'John Doe'
Setter 属性
Setter 属性允许我们将计算属性设置为模型中其他属性的值。例如,我们可以定义一个包含生日的模型,并计算出年龄虚拟属性:
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ---------- ------- --------- ------- --------- ---- --- --------------------------------------------- - ----- ----------- - --- --------------------- ----- --------- - -------------------- -------------------- ------- --------------- ----------- - ----------- --- ----- ---- - ---------------------- ------------
在上面的代码中,我们使用 virtual()
方法定义了一个虚拟属性 age
,通过 set()
方法设置了它的值。这个 setter
函数首先从传入的 Date
值中提取生日年份,并计算出当前年份与生日年份之间的差值。然后,它使用 set()
方法设置 age
属性和生日属性的值。
现在我们可以设置用户的年龄:
const user = new User({ firstName: 'John', lastName: 'Doe', birthday: new Date('1986-10-15') }); user.age = 35; console.log(user.birthday);
由于我们使用 setter
函数来设置 age
属性的值,这也会更新生日属性的值。
虚拟参考字段
虚拟参考字段是在 MongoDB 中使用 $lookup
操作符自动执行的类似外部关联字段。虚拟参考字段是可以根据关联的文档计算得到的字段,与虚拟属性不同的是,虚拟参考字段可以映射到自己的集合中其他文档。
由于实现虚拟参考字段需要涉及到关联操作,因此我们需要创建两个模型。这里我们假设有一个模型 User
,和另一个模型 Post
。User
模型有一个 _id
属性,并存储在 Post
文档中的 author
中。
现在,我们需要从 Post
模型中获取所有帖子,并将其与创建它们的用户关联起来。我们可以通过创建一个虚拟参考字段来实现这一点:
-- -------------------- ---- ------- ----- ---------- - --- ----------------- ------ ------- -------- ------- ------- - ----- ------------------------------- ---- ------ - --- ----------------------------------- - ---- ------- ----------- --------- ------------- ----- --- ----- ---- - ---------------------- ------------
在上面的代码中,我们使用 virtual()
方法将 authorDetails
字段定义为虚拟参考字段。我们将 ref
属性设置为 User
模型,并使用 localField
和 foreignField
属性将 author
属性与 _id
属性关联起来。
现在,我们可以使用 Mongoose 的 populate()
方法来对虚拟参考字段进行填充:
Post.find().populate('authorDetails').exec(function(err, posts) { // done });
上面的代码中,我们调用 populate()
方法并传入 authorDetails
参数,这会填充虚拟参考字段,并将 User
文档添加到 authorDetails
属性中。
总结
通过使用 Mongoose 的虚拟属性和虚拟参考字段功能,我们可以创建一个更加灵活和可维护的数据库模型。计算属性和 Setter 属性可以根据其他属性自动生成值,而虚拟参考字段可以用于从多个集合中提取数据。这些特性不仅可以提高性能,还可以减少数据冗余,更好地组织代码。
参考示例代码如下:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ---------- - ------------------------------------------------------------- ----- ---------- - --- ----------------- ---------- ------- --------- ------- --------- ---- --- --------------------------------------------- - ------ -------------- - - - - -------------- --- --------------------------------------------- - ----- ----------- - --- --------------------- ----- --------- - -------------------- -------------------- ------- --------------- ----------- - ----------- --- ----- ---- - ------------------------ ------------ ----- ---------- - --- ----------------- ------ ------- -------- ------- ------- - ----- ------------------------------- ---- ------ - --- ----------------------------------- - ---- ------- ----------- --------- ------------- ----- --- ----- ---- - ------------------------ ------------ ----- ----------- - --- ------ ---------- ------- --------- ------ --------- --- ------------------ --- ----- ----------- - --- ------ ------ -------- ------ -------- ----- -- -- ------- ------- ------- --------------- --- ------------------- -- - ------------------------------------------------ ------ -- - ------------------- ---------------------- --- ---
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6476d986968c7c53b03772f0