在 Mongoose 中,我们可以使用虚拟属性(virtuals)来创建一些计算属性,这些属性并不会被存储在数据库中,而是通过其他属性计算获取的。虚拟属性在一些场景下非常方便,比如对于某些数值型字段,我们可能需要对其进行一些计算后再进行展示或者操作,这时候虚拟属性可以大大简化代码和逻辑。
为了便于讲解,我们接下来会使用一个博客应用来进行示例。假设我们有以下两个 mongoose 模型:
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ---------- - --- ----------------- ------ ------- -------- ------- ------- ------ --- ----- ---------- - --- ----------------- ----- ------- ------ - ----- ------- ------- ---- -- ------ -- ----- ------------------------ ---- ------ -- --- ----- ---- - ---------------------- ------------ ----- ---- - ---------------------- ------------ -------------- - - ----- ---- --
接下来,我们来讲解两种虚拟属性的创建方法。
1. 使用 get
和 set
通过 get
和 set
方法,我们可以创建虚拟属性。
假设我们有一个 Post
模型,它有点赞数和评论数两个属性,我们需要计算它们的和作为一个虚拟属性。这时候,我们可以使用以下代码(注意,这里我们需要使用 function
关键字来声明函数,这样可以访问到 this
对象):
postSchema.virtual('totalCommentsAndLikes').get(function() { return (this.likes || 0) + (this.comments || 0); }); postSchema.set('toObject', { virtuals: true }); postSchema.set('toJSON', { virtuals: true });
以上代码中,我们使用 postSchema.virtual
方法来声明虚拟属性,它接收两个参数,第一个参数是虚拟属性的名称,第二个参数是一个对象,包含 get
和 set
两个方法来访问和设置虚拟属性。在我们的示例中,我们只需要使用 get
方法即可。此外,我们还通过 set
方法将虚拟属性添加到 toObject
和 toJSON
两个选项中,这样在使用 res.send
或者 console.log
等方法输出 Post
对象时,我们也可以看到虚拟属性的值。当然,如果你不希望在 toObject
或者 toJSON
中输出虚拟属性,你可以将这两个选项的值设为 false
。
通过以上配置,我们可以这样来读取虚拟属性:
Post.findOne({ title: 'xxx' }).exec((err, post) => { console.log(post.totalCommentsAndLikes); // => 233 });
接下来,我们再来看一种创建虚拟属性的方式。
2. 使用 virtuals
属性
通过 virtuals
属性,我们也可以简单地创建虚拟属性。
我们来看一下以下示例代码:
userSchema.virtual('postCount').get(function() { return this.posts.length; });
以上代码中,我们使用 userSchema.virtual
方法声明虚拟属性,它也接收两个参数,第一个参数是虚拟属性的名称,和上面的方式一样;第二个参数是一个对象,包含 get
和 set
两个方法,和上面的方式不同的是,在这种方式中我们使用一个对象来传递虚拟属性的 get 函数。
注意,在使用这种方式创建虚拟属性时,我们不能够使用 toObject
和 toJSON
中输出虚拟属性的方法,而是需要在读取模型时手动调用 toJSON
方法来获取虚拟属性的值:
User.findOne({ email: 'xxx@xxx.com' }).populate('posts').exec((err, user) => { const { postCount } = user.toJSON(); console.log(postCount); // => 20 });
总结
本文针对 mongoose 中的虚拟属性进行了详细的讲解,并提供了两种方式来创建虚拟属性。希望读者能够通过本文学会如何使用虚拟属性来优化自己的代码。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/648dac0548841e9894c04494