I'm trying to learn MongoDB/Node and I noticed that in a schema I often see something like this:
toObject: { virtuals: true }
toJSON: { virtuals: true }
What do these two lines mean?
I'm trying to learn MongoDB/Node and I noticed that in a schema I often see something like this:
toObject: { virtuals: true }
toJSON: { virtuals: true }
What do these two lines mean?
Share Improve this question edited Jun 23, 2017 at 22:21 Neil Lunn 151k36 gold badges354 silver badges324 bronze badges asked Nov 13, 2014 at 13:00 oheasoheas 1551 gold badge1 silver badge7 bronze badges 2- You know that the general practice here is to "accept" answers that help you. That's big "tick" thing next to the answer rating number. Saying this because you have not accepted a single answer to all of the questions you have asked. They cannot all be wrong so accept them. – Neil Lunn Commented Nov 13, 2014 at 13:36
- Have you read the documentation on these options? – JohnnyHK Commented Nov 13, 2014 at 13:41
1 Answer
Reset to default 20This is not "MongoDB" but specific to the mongoose ODM.
Mongoose has a concept of "virtual" fields in the schema definition. This essentially allow this (blatant glean from documentation):
var personSchema = new Schema({
name: {
first: String,
last: String
}
});
var Person = mongoose.model( "Person", personSchema );
But suppose you just want to "store" those properties but then have something you can access in code called "fullname". This is where "virtuals" come in:
personSchema.virtual("name.full").get(function () {
return this.name.first + ' ' + this.name.last;
});
Now we can do something like this:
var bad = new Person({
name: { "first": "Walter", "last": "White" }
});
console.log("%s is insane", bad.name.full); // Walter White is insane
So the name.full
does not actually exist in the data, it's just a schema representation in code. But of course "tied" to a function that uses the actual data present in the object to make a method that returns a value combining the two fields per the code in the method.
This is basically what "virtual" fields are about. They are actually "methods" defined on the document "object" that present a value that is not "stored" or persisted in the database. Usually they are based on actual persisted values from the data storage.
But to really clear up your direct question. Mongoose only 'serializes' the content of it's internal object structure based on the "stored" fields by default. So what those two lines "really" mean are:
toObject(): This produces a "plain" or "raw" representation of the object data without all the other "mongoose magic" parts of the extended object. But the purpose of "virtuals" is to make those methods part of the object returned. Basically just the plain object, called as:
var model = Model.new({ "name": { "first": "Walter", "last": "White" }); console.log( model.toObject() );
toJSON(): You can call this method explicitly and just as shown above, but it's most common usage is from a JSON parser like below where it is implicitly called. The same principles apply as above. The "virtuals" includes the result of those methods in the serialized output, such as:
var model = Model.new({ "name": { "first": "Walter", "last": "White" }); JSON.stringify( model, undefined, 2 );
So the second case there is an "implicit" call of the .toJSON()
method on the object. What the configuration is doing is telling that method to not only include data or "fields" present in the object, but also the "virtual" methods defined and the output they give as well. Same for .toObject()
.