This is a good question that illustrates the problems with overwork and how to deal with it.
Example: Post like
Letβs follow the example of users who love messages, which is a simple example. Other relationships should be handled accordingly.
You are absolutely right that with the preservation of such messages inside the message, sooner or later it will lead to a problem when the size of very popular messages is reached.
So, you stepped back correctly to create the post_likes collection. Why do I call it right? Since it is suitable for your use cases and functional and non-functional requirements!
- It scales indefinitely (well, there is a theoretical limit, but it is very large)
- It is easy to maintain (create a unique index over
post_id and liked_user_id ) and use it (both the user and the mail are known, so adding this is a simple insert or, most likely, upsert) - You can easily find out who likes this publication and which publication will appeal to those with whom users
However, I would expand the collection a bit to prevent unnecessary queries for some commonly used use cases.
Assume publication names and usernames cannot be changed. In this case, the following data model may make more sense.
{ _id: new ObjectId(), "post_id": someValue, "post_title": "Cool thing", "liked_user_id": someUserId, "user_name": "JoeCool" }
Now suppose you want to display the username of all users who liked the post. With the model above, this will be one rather quick request:
db.post_likes.find( {"postId":someValue}, {_id:0,user_name:1} )
If you save only identifiers, this rather common task will require at least two queries, and - given the restriction that there can be an infinite number of instances for memory consumption it is potentially huge (you'd need to store user identifiers in RAM).
Of course, this leads to some redundancy, but even when millions of people love mail, we are only talking about a few megabytes of relatively cheap (and easily scalable) disk space, getting more performance in terms of user convenience.
Now here's the thing: even if the usernames and message headers can be changed, you only need to make a few updates:
db.post_likes.update( {"post_id":someId}, { $set:{ "post_title":newTitle} }, { multi: true} )
You trade, it takes some time to do some fairly rare things, such as changing a username or message for extreme speed for use cases that happen very often.
Bottom row
Keep in mind that MongoDB is a documented database. Thus, document the events of interest to you with the values ββneeded for future queries, and model your data accordingly.