Reputation: 975
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
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
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