0

In my React app, I have collections User, Post, Like, and Comment.

The users can both comment and like posts.

My comment collection has fields post_id, user_id, and text.

My like collection has fields post_id and user_id.

But I want the users to vote comments up or down (just like on SO).

What should the database structure be like? I could have two fields in each comment user_ids_vote_up and user_ids_vote_down which are just arrays of user ids. But is this the right approach? I have read many places that the documents are limited in size, so the right thing is to store these votes/likes in a separate collection.

Jamgreen
  • 10,329
  • 29
  • 113
  • 224
  • 1
    For the record an `ObjectId` ( as a reasonable unique identifier ) is `12-bytes` and the BSON Hard limit is 16MB. So what are you building? That's a lot of 12-byte votes to actually break that limit. Not sure what the most upvoted question is on SO, but I'm pretty sure it does not come close to 500K+ votes both up and down. Design is really most appropriate to your actual use case, and for "huge" you generally handle the edge cases differently to the "most general" optimal cases. KInd of opinion based, but I do challenge you to break a BSON limit on upvotes alone. – Neil Lunn Oct 13 '17 at 07:43
  • I see the point! Thanks! I need to order the comments by the sum of votes (i.e., upvotes - downvotes). Also, in the future, I need to know which posts each user has upvoted/downvoted to make a recommendation system (users who liked post X, also liked post Y - even though they only liked a comment on the post). It might be easier to extract who liked what with a separate collection (`Vote.find({ post_id: x, user_id: y })`), but it sounds like it's easier to just have two arrays in the comments. But maybe the reason to have it in a separate collection could be to handle many concurrent votes? – Jamgreen Oct 13 '17 at 08:09
  • I don't really see that sort of comparison you mention as being a restriction. If you are thinking along the lines of "all the votes in one collection" then if all the votes are "on the posts in the same collection" then they are still all in the same collection. Like I said it kind of gets opinion based on one way or the other. The one thing I will say is that "joins do cost" which was therefore a primary reason why the "initial stance" was "MongoDB would not do joins", but of course that stance has been relaxed. – Neil Lunn Oct 13 '17 at 08:26
  • At any rate the "array case", which honestly IMHO you actually should try first until you find that you actually break it ( which should be a real challenge ) does have some pointers on design and usage right here [How to Model a “likes” voting system with MongoDB](https://stackoverflow.com/a/28006849/2313887). And even there it is mentioned that "Hybrid design" is usually *where to go from there* in scaling upwards. – Neil Lunn Oct 13 '17 at 08:29
  • Okay thanks! I will go with that! But what if I need both upvotes and downvotes like SO? Will I need 4 functions: vote up, remove vote up, vote down, remove vote down, or is it more clever to make an array of vote objects `{ user_id: x, vote: 3 }` where 3 represents something? – Jamgreen Oct 13 '17 at 08:41

0 Answers0