Hi!
Is there any way to implement inheritance between two schemas? I'm going to explain it better.
I have a model called UserModel, and I have subclasses called FacebookLoginModel and GoogleLoginModel, both extendin the first one:
export class UserModel {
_id:mongoose.Types.ObjectId;
@prop({ required: true })
loginType:LoginType;
@prop({ required: true })
name:string;
}
export class GoogleLoginModel extends UserModel {
/*
some properties
*/
}
export class FacebookLoginModel extends UserModel {
/*
some properties
*/
}
My problem is that I want to persist the different models in the same collection (users), but I want preserve de singularity of the subclasses.
Thanks!
so basically you want discriminators
https://typegoose.github.io/typegoose/docs/functions/getDiscriminatorModelForClass/
https://mongoosejs.com/docs/discriminators.html
Okey, Thanks a lot!
this issue seems to be solved
if someone stumbles upon it, here's an updated link to descriminators docs
https://typegoose.github.io/typegoose/docs/api/functions/get-discriminator-model-for-class/
https://typegoose.github.io/typegoose/docs/api/decorators/prop/#discriminators
Hey 馃憢 Another question: is it possible to create a hierarchy? Let's say User -> Staff -> Admin and so on? So kind of embedded discriminators? I think that would be perfect
Didn't have that much knowledge about mongoose & typegoose before, designed the app with this feature in mind but it turned out it can not be nested for more than one level
Any ideas?
@AmirAlOmari - You have only the three tools in MongoDB/ Mongoose to work with for relationships. Subdocuments, Refs and Discriminators. Whereas, discriminators aren't relational per se. They are more a way to save on needing additional collections to model quite similar things or as Mongoose puts it, discriminators are a schema inheritance mechanism. With refs, you can do as many levels of hierarchy as you'd like. And, with the auto-populate plug-in, you can "auto-"recall data up to 10 levels deep (which I'd suggest is a really bad idea. 3 max is my rule).
What you need to think about with MongoDB is, what needs to be a relationship between entities as collections or as subdocuments. As long as the number of relationships is finite and will stay relatively small, you'll want to use subdocuments, as they can be gotten in a single query with the entity data. If there is at all a chance that the number of relations can become large (like more than a few 100 as my rule), then you'd need to put the related data in a collection and not in sub-documents.
Then there are the reasons to access the data, which also come into play. With your example, I'd say it is a mix of refs and discriminators. User -> Staff -> Admin. I'd suggest a User is an entity mainly needed for the application. Staff is one of the business' main entities. So, being they have very different purposes, i.e. the reasons to access them differ a lot, they should be very much their own collections, so they should be related via refs (first hierarchical relationship). Between Staff and Admins, I'd say Admins are a type of staff, so here, a discriminator could more than likely be a good choice. You have more than likely other types of staff too and it is only a difference in fields. So, you could have a base set of "staff" fields, and an Admin might have some additional fields to those base fields. That is what discriminators are used for. From the different "record types", which discriminators can offer, you can also have refs and sub-documents, so extending a hierarchy.
What is important to note is, every ref is an additional call for the database's client driver (via Mongoose) to go and grab the data. It is not a step taken in the database, like it is with relational databases. In other words, joining data is programmatic and not systematic with MongoDB.
So, with MongoDB you can model relational data hierarchically for sure. It's up to you to model those relations so MongoDB and Mongoose can work best with them. Some people say, if you are working with very relational data, MongoDB is a bad choice. I sort of disagree with that comment. It's not that simple. All data is relational in some way or another. The question is, how is data accessed and stored for your app? If there are a lot of relational connections between your entities, like more than a few, or if the depth of data needed to be recalled is high in the relations i.e. via hierarchies, and they all can't be broken down to be simpler in some way (via sub-documents), then MongoDB might be the wrong tool.
Scott
Most helpful comment
@AmirAlOmari - You have only the three tools in MongoDB/ Mongoose to work with for relationships. Subdocuments, Refs and Discriminators. Whereas, discriminators aren't relational per se. They are more a way to save on needing additional collections to model quite similar things or as Mongoose puts it, discriminators are a schema inheritance mechanism. With refs, you can do as many levels of hierarchy as you'd like. And, with the auto-populate plug-in, you can "auto-"recall data up to 10 levels deep (which I'd suggest is a really bad idea. 3 max is my rule).
What you need to think about with MongoDB is, what needs to be a relationship between entities as collections or as subdocuments. As long as the number of relationships is finite and will stay relatively small, you'll want to use subdocuments, as they can be gotten in a single query with the entity data. If there is at all a chance that the number of relations can become large (like more than a few 100 as my rule), then you'd need to put the related data in a collection and not in sub-documents.
Then there are the reasons to access the data, which also come into play. With your example, I'd say it is a mix of refs and discriminators. User -> Staff -> Admin. I'd suggest a User is an entity mainly needed for the application. Staff is one of the business' main entities. So, being they have very different purposes, i.e. the reasons to access them differ a lot, they should be very much their own collections, so they should be related via refs (first hierarchical relationship). Between Staff and Admins, I'd say Admins are a type of staff, so here, a discriminator could more than likely be a good choice. You have more than likely other types of staff too and it is only a difference in fields. So, you could have a base set of "staff" fields, and an Admin might have some additional fields to those base fields. That is what discriminators are used for. From the different "record types", which discriminators can offer, you can also have refs and sub-documents, so extending a hierarchy.
What is important to note is, every ref is an additional call for the database's client driver (via Mongoose) to go and grab the data. It is not a step taken in the database, like it is with relational databases. In other words, joining data is programmatic and not systematic with MongoDB.
So, with MongoDB you can model relational data hierarchically for sure. It's up to you to model those relations so MongoDB and Mongoose can work best with them. Some people say, if you are working with very relational data, MongoDB is a bad choice. I sort of disagree with that comment. It's not that simple. All data is relational in some way or another. The question is, how is data accessed and stored for your app? If there are a lot of relational connections between your entities, like more than a few, or if the depth of data needed to be recalled is high in the relations i.e. via hierarchies, and they all can't be broken down to be simpler in some way (via sub-documents), then MongoDB might be the wrong tool.
Scott