Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongo db - schema for implementing like feature in webapp

i have a mongodb database, in which i got 2 collections. posts and users.

posts json structure is like

{title:"Title", content:"content goes here", postedby: "userid"}

and users is like

{username:"", name:""}

Now i need to implement a like feature, where users like the posts.

Solution 1

i can put an inner array in users like

{username:"", name:"", likes:[postid1,postid2..]}

issue here is its easy to query posts which a user liked. But difficult to get people who liked an article.

Solution 2

i can put an inner array in posts like

{title:"Title", content:"content goes here", postedby: "userid", like:[userid1,userid2 ..]}

issue here is its easy to get people who liked an article. But difficult to query posts which a user liked.

How can i tackle this? currently i am thinking about having both the ways. Just like keeping inner arrays in both collections. I know i am keeping redundant data, is it the best way to approach this issue?

like image 258
Mithun Satheesh Avatar asked Feb 04 '13 07:02

Mithun Satheesh


1 Answers

I personally would not go for a like array here.

It is all too common that likes grow out of control with a person liking way too many posts; to the point where this could hinder the amount of top level user data you could store in that document.

You have also got to consider your querying pattern here. You will most likely want to do some sort of graphed aggregation of likes across multiple users. Currently to do such a thing dynamically you must use the aggregation framework: http://docs.mongodb.org/manual/applications/aggregation/ (pre-aggregative reports: http://docs.mongodb.org/manual/use-cases/pre-aggregated-reports/ would also be a useful tool here but I will skip that) using $unwind.

$unwind is a in-memory operation which can be slow on distanced aggregation of many users especially if each user sits on at least 1000 likes (50x1000 is already pushing the in-memory limit for $unwind and a post $group $sort, which has a memory limit of 10% of the systems memory). All in all the aggregation framework will not a peformant method to query for these likes.

MongoDB can easily store this structure though, evne in its gorwing form since the subdocument is like maybe 12 bytes for each entry so you can just use power of 2 sizes ( http://docs.mongodb.org/manual/reference/command/collMod/#usePowerOf2Sizes ) allocation to remedy the problems you would normally get (fragmentation) with using the structure.

So considering this I would keep likes in a separate collection. It is true that you will lose the single round trip notation of housing the likes in the user document but I believe that what I stated above is worth the price.

like image 138
Sammaye Avatar answered Sep 28 '22 08:09

Sammaye