deno.land / x / mongoose@6.7.5 / docs / tutorials / virtuals.md
In Mongoose, a virtual is a property that is not stored in MongoDB. Virtuals are typically used for computed properties on documents.
Suppose you have a User
model. Every user has an email
, but you also
want the email's domain. For example, the domain portion of
'test@gmail.com' is 'gmail.com'.
Below is one way to implement the domain
property using a virtual.
You define virtuals on a schema using the Schema#virtual()
function.
[require:Virtuals.*basic]
The Schema#virtual()
function returns a VirtualType
object. Unlike normal document properties,
virtuals do not have any underlying value and Mongoose does not do
any type coercion on virtuals. However, virtuals do have
getters and setters, which make
them ideal for computed properties, like the domain
example above.
You can also use virtuals to set multiple properties at once as an
alternative to custom setters on normal properties. For example, suppose
you have two string properties: firstName
and lastName
. You can
create a virtual property fullName
that lets you set both of
these properties at once. The key detail is that, in virtual getters and
setters, this
refers to the document the virtual is attached to.
[require:Virtuals.*fullName]
By default, Mongoose does not include virtuals when you convert a document to JSON.
For example, if you pass a document to Express' res.json()
function, virtuals will not be included by default.
To include virtuals in res.json()
, you need to set the
toJSON
schema option to { virtuals: true }
.
[require:Virtuals.*toJSON]
console.log()
By default, Mongoose does not include virtuals in console.log()
output.
To include virtuals in console.log()
, you need to set the toObject
schema option to { virtuals: true }
, or use toObject()
before printing the object.
console.log(doc.toObject({ virtuals: true }));
Virtuals are properties on Mongoose documents. If you use the
lean option, that means your queries return POJOs
rather than full Mongoose documents. That means no virtuals if you use
lean()
.
[require:Virtuals.*lean]
If you use lean()
for performance, but still need virtuals, Mongoose
has an
officially supported mongoose-lean-virtuals
plugin
that decorates lean documents with virtuals.
Mongoose virtuals are not stored in MongoDB, which means you can't query based on Mongoose virtuals.
[require:Virtuals.*in query]
If you want to query by a computed property, you should set the property using a custom setter or pre save middleware.
Mongoose also supports populating virtuals. A populated virtual contains documents from another collection. To define a populated virtual, you need to specify:
ref
option, which tells Mongoose which model to populate documents from.localField
and foreignField
options. Mongoose will populate documents from the model in ref
whose foreignField
matches this document's localField
.[require:Virtuals.*populate]
Version Info