xbd
xbd

Reputation: 975

Clarification and difference between different methods of nesting Schema in Mongoose

I am trying to nest Schema within Schema, and I found multiple ways of doing it in Stackoverflow, and I am wondering what's the difference

Mongoose schema within schema

var TaskSchema = new Schema({
    user : Schema.ObjectId
});

Is it possible to reference two schemas to eachother in Mongoose?

var emailSchema = new Schema({
   Subject : FoodItemSchema,
   FoodItems : [FoodItemSchema],
   Owner : { type : Schema.Types.ObjectId , ref: "User" }
});

I didn't understand why you can't do the following to accomplish the task

var TaskSchema = new Schema({
    user : UserSchema
});

or

var emailSchema = new Schema({
   Subject : FoodItemSchema,
   FoodItems : [FoodItemSchema],
   Owner : { type : OwnerSchema , ref: "User" }
});

And I am quite confused on what is the difference between

Schema.Types.ObjectId

and

Schema.ObjectId

Thanks

Upvotes: 1

Views: 372

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151220

There is no real difference between those two statements, in correct long for it is actually Schema.Types.ObjectId but the other form is there for convenience. Or you could even directly import it.

Now with the following there is a distinct difference in the implementation:

var emailSchema = new Schema({
   Subject : FoodItemSchema,
   FoodItems : [FoodItemSchema],
   Owner : { type : Schema.Types.ObjectId , ref: "User" }
});

In the items that refer to FoodItemSchema what this actually does is "embed" the document within the document represented. In one form as a simple sub-document and in the other as an array of those sub-documents.

This is a feature of MongoDB where you can keep your "related" document information "within" the actual document itself. In many cases this is the most efficient thing to do.

But in the other form for the field Owner all that is being kept is the document _id value that "refers" to an item in a separate collection where "User" is the name of the schema used. Typically this will be used with an array, but in this instance it is just a single document reference.

So the actual stored document of the emailSchema in it's model does not actually contain the "User" information as opposed to the "embedded" form. All that is contained is the _id value of the document that exists in a separate collection.

Mongoose provides the populate method in order to allow the "merging" of the document from the other collection into this document on retrieval. The result it will "appear" as if the document was actually embedded when it was not.

But population, while handy, is only actually going back to the database with an additional query or queries in order to "fetch" that information. So depending on your needs this could be a performance issue.

So that should basically explain the differences. You can also look at the documentation references given for further examples. There is also a good section in the MongoDB documentation on Data Modelling that discusses various approaches using embedding or alternately using "linked references" such as Mongoose provides.

Upvotes: 2

Related Questions