Hey community.
I was having an Issue with my schema design in my user document,
In my scenario, users can follow each other or becoming friends (if both sides have each other followed).
for having a easy to manage and accessible way, I used to store all the user relations in his own document like
UserDocument : {
user_name : "test",
followers : [ collection of other user ids],
followings : [ collection of other user ids],
friends : [ collection of other user ids],
}
it was completely okay for a short amount of users, but the problem comes with a user with like 5000 followers and like 6000 followings and 1000 friends, you know ! that 16 mb won’t be enough.
the first think I knew that I have to do was to separate the relations, but I didn’t know the most appropriate way.
after studying about data modeling, schema design patterns and some more blogs etc…
I find out that I need to first understand that we first need to find-out what we need.
is the database have more read than writes or wise-versa ??
then I came up with the following questions
question : how this data will be needed, and when???
answer : when fetching user in some scenarios, we need to have user relations to check privacy and relation with another users and we need all of it not just a part.
the current solutions :
the first thing that I came up with is a separate collection like this :
RelationDocument : {
user_id : "user_id",
relation_type : 'following',// or follower or friend
related_user_id : "the user Id that I followed",
status : 'pending' or accepted
}
if a user A follows the user B we create a document for each one of the users.
it means that we will have 6 documents if two users are become friends. is it okey??
then I find the bucket pattern which says, you can decrease the number of documents by storing the data together based time frames.
in my scenario the time frames doesn’t fit but I can change it with relation count (e.g. 500 relations) in one doc.
which is reasonably makes sense: the the final document can be something like this:
Bucket-Pattern-Based-Relation-Document:{
"user_id":"testing guid",
"relations" : [
{
"related_user_id" : "the user",
"type" : "following",
"status" : "pending"
},
.... more and more.
],
"relation_count" : 100 // max count is 500
}
then I find out another pattern called Outlier, which is also can be considered as a solution,
in this pattern, you don’t put yourself in trouble for all the documents in a collection and change your whole initial design.
instead you give documents the ability to grow. and it’s all up to them
the interesting point about is it looks great when you combine it with the Bucket-Pattern (the over flowed data would be stored as buckets)
the sample document would be :
Out-Lier-Based-User-Document: {
"user_id":"testing guid",
"relations" : [{
"related_user_id" : "the user",
"type" : "following",
"status" : "pending"
}],
"relation_count": 40, // max would be 300
"relation_overflowed" : false
}
and over-flowed relation would be
{
"user_id" : "testing_userid",
"relations" : [{
"related_user_id" : "another userId",
"type" : "following",
"status" : "accepted"
}],
"relation_count" : 30 // max would be 400 or something like that.
}
what do you think guys about this solutions, do you think is any of these suitable for my scenario?
I’ll appreciate any comment’s and thoughts about it.