Virtual attributes
Mongoose supports virtual attributes. Virtual attributes are attributes
that are convenient to have around but that do not get persisted to mongodb.
An example is helpful.
Example
Take the following schema:
var PersonSchema = new Schema({
name: {
first: String
, last: String
}
});
var Person = mongoose.model('Person', PersonSchema);
var theSituation = new Person({
name: { first: 'Michael', last: 'Sorrentino' }
});
Suppose you want to write theSituation
's full name. You could do so via:
console.log(theSituation.name.first + ' ' + theSituation.name.last);
It is more convenient to define a virtual attribute, name.full
, so you can instead write:
console.log(theSituation.name.full);
To do so, you can declare a virtual attribute on the Schema, Person
:
PersonSchema
.virtual('name.full')
.get(function () {
return this.name.first + ' ' + this.name.last;
});
So when you get name.full
, via
theSituation.name.full;
the implementation ends up invoking the getter function
function () {
return this.name.first + ' ' + this.name.last;
}
and returning it.
It would also be nice to be able to set this.name.first
and this.name.last
by setting this.name.full
. For example, it would be nice if we wanted to change theSituation's name.first
and name.last
to 'The' and 'Situation' respectively just by invoking:
theSituation.set('name.full', 'The Situation');
Mongoose allows you to do this, too, via virtual attribute setters. You can define a virtual attribute setter thusly:
PersonSchema
.virtual('name.full')
.get(function () {
return this.name.first + ' ' + this.name.last;
})
.set(function (setFullNameTo) {
var split = setFullNameTo.split(' ')
, firstName = split[0]
, lastName = split[1];
this.set('name.first', firstName);
this.set('name.last', lastName);
});
Then, when you invoke:
theSituation.set('name.full', 'The Situation');
and you save the document, then name.first
and name.last
will be changed in monbodb, but the mongodb document will not have persisted a name.full
key or value to the database:
theSituation.save(function (err) {
Person.findById(theSituation._id, function (err, found) {
console.log(found.name.first); // 'The'
console.log(found.name.last); // 'Situation'
});
});
If you want attributes that you can get and set but that are not themselves persisted to mongodb, virtual attributes is the Mongoose feature for you.