虚拟字段并不真实存在于数据库中,但是在Mongoose文档中和普通字段中扮演着同样的角色。
简单来讲,虚拟字段除了不会存入数据库外,其他方面和普通字段没有区别。
一、用虚拟字段创建聚合字段是很不错对选择。
例如:如果我们的系统需要有姓、名以及全名等字段(全名不过是姓和名连接起来),所以除了姓、名的值不需要再存储全名的值。
我们需要做的只是在虚拟字段里将姓和名连接起来。
二、其他用例是使数据库向下兼容。
例如,我们可能在一个MongoDB集合中有成千上万的用户条目,然后我们想收集他们的位置信息。
这时有两个选择:
1.一种是运行一个迁移脚本向成千上万个老的用户文档中增加默认的位置信息(none)
2.另一种是运行时使用一个默认配置的虚拟字段。
三、定义一个虚拟字段我们需要:
1.调用virtual(name)方法来创建一个虚拟类型
2.使用get(fn)方法来应用getter函数
例如Gravatar网站:
是一个提供头像图片服务的站点。他的URL通常是用户邮箱的md5加密串。
因此,我们可以通过使用虚拟字段来获取经过动态散列的gravatarUrl虚拟值,而无需存储这个值(减轻负载)。
在接下来的例子中,我们故意使输入的email大小写混合,同时增加一个空格,然后应用加密:
Identity.virtual('gravatarUrl')
.get(function(){
if(!this.email) return null;
var crypto = require('crypto'),
email = 'LiJian_17@163.com ',
email = email.trim();
email = email.toLowerCase();
var hash = crypto
.createHash('md5')
.update(email)
.digest('hex');
var gravatarBaseUrl = 'https://secure.gravatar.com/avatar/';
return gravatarBaseUrl + hash;
});
之前提到的用例—通过姓、名得到全名,代码如下:
userSchema.virtual('fullName')
.get(function(){
return this.firstName + ' ' + this.lastName;
})
其他场景是当整个文档的一个子集是需要暴露的。
如下所示:如果用户模型有令牌和密码,我们使用白名单忽略这些敏感的字段,只返回那些我们需要暴露的字段:
userSchema.virtual('info')
.get(function(){
return{
service: this.service,
username: this.username,
name: this.name,
date: this.date,
url: this.url,
avatar: this.avatar
};
});