Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
116
rated 0 times [  121] [ 5]  / answers: 1 / hits: 9483  / 10 Years ago, thu, november 13, 2014, 12:00:00

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?


More From » node.js

 Answers
18

This 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:




  1. 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() );

  2. 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().


[#41277] Wednesday, November 12, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
raveno

Total Points: 453
Total Questions: 92
Total Answers: 92

Location: France
Member since Thu, Oct 27, 2022
2 Years ago
;