1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
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.
|