Virtual Properties in Mongoose
Virtual properties in Mongoose are document properties that you can get and set but that do not get persisted to the MongoDB database. They are typically used to define computed values or combine multiple fields dynamically, improving code readability and maintaining data normalization.
Table of Content
What Are Virtual Properties?
- Virtuals are properties that do not get stored in MongoDB but behave like normal document properties.
- They allow you to define computations or transformations based on existing document fields.
- Mongoose calls the getter function each time the virtual property is accessed.
- You can also define setters to update underlying document fields when setting a virtual.
Defining Virtual Properties
Use the schema.virtual()
method to define a virtual:
const userSchema = new mongoose.Schema({
firstName: String,
lastName: String
});
userSchema.virtual('fullName').get(function() {
return this.firstName + ' ' + this.lastName;
});
Using Getters and Setters
Virtuals can have both getter and setter functions:
userSchema.virtual('fullName')
.get(function() {
return this.firstName + ' ' + this.lastName;
})
.set(function(name) {
const split = name.split(' ');
this.firstName = split[0];
this.lastName = split[1];
});
Example: Full Name Virtual
Here is a complete example showing usage of a virtual property:
const User = mongoose.model('User', userSchema);
const user = new User({ firstName: 'John', lastName: 'Doe' });
console.log(user.fullName); // John Doe
user.fullName = 'Jane Smith';
console.log(user.firstName); // Jane
console.log(user.lastName); // Smith
Schema Options for Virtuals
Enable virtuals to be included in JSON and Object outputs:
const userSchema = new mongoose.Schema({
firstName: String,
lastName: String
}, {
toJSON: { virtuals: true },
toObject: { virtuals: true }
});
Benefits of Using Virtuals
- Keep your database schema clean by not storing computed values.
- Compute values dynamically to reflect changing data.
- Improve code clarity by accessing computed properties like normal fields.
- Avoid data duplication and maintain normalization.
Quick Reference Table
Feature | Description | Example |
---|---|---|
Virtual Property | Non-persistent computed property | schema.virtual('fullName').get(...) |
Getter | Returns the computed value | .get(function() { return ... }) |
Setter | Sets fields based on input | .set(function(val) { ... }) |
Include in JSON | Set toJSON: { virtuals: true } in schema options |
Serialization includes virtuals |
Best Practices
- Use virtuals for computed, derived, or formatted data.
- Do not store redundant computed fields in the database.
- Always enable virtuals in
toJSON
ortoObject
if you want them serialized. - Keep getter and setter logic simple and performant.
Conclusion
Virtual properties in Mongoose are a powerful feature that allows you to add logical properties to your documents without storing them in MongoDB. By using virtuals, you can create dynamic computed fields, reduce redundancy, and keep your code clean and expressive.
Comments
Post a Comment