Community comments & vote schema redesign for growth/scale


#1

Hi everyone, I’m trying to plan how to scale the MVP of https://www.product.cafe. It’s best you just quickly check out the site but here’s the TL;DR:

Product Cafe is a community for product managers. Users can:

  • Share relevant product management stories
  • Ask a product management question and get advice from other users
  • Post a product job and/or find product jobs
  • There’s a self-curated podcast

Additional types of contents in the future will be:

  • Interviews with successful product teams
  • User curated case studies on products built

All of the existing and future features have one thing in common:
They all have a commenting system and they should all have a voting system assigned to them.

I’ve been hacking the MVP together quickly, I want to make sure the Mongoose/GraphQL schema is ready for future scaling.

Right now I have the following concern on how to structure the schema: Currently individual types of content (story, question, etc.) all have their own votes field (that gets incremented as users vote).

For comments, there is a schema just for that and my comment component gets the ID of the DB entry (doesn’t matter which model it is such as StoryModel, QuestionModel, etc it just gets the _id) and then I retrieve all comments that refer to that ID. This works well for me. I was thinking if I should do the same for votes? That way I can simply refer to the vote ID and get the number of votes.

With my current system, I have to run a custom mutation such as addVoteToStory, addVoteToQuestion, etc… If I’d just have one addVote mutation taking the id it refers to, that would make things a lot simpler and I could easily attach votes to anything. I’m just not sure how efficient it is to do these kind of decouplings?

Old schema:
StoryModel, QuestionModel - each contains vote separately as Number being incremented
CommentsModel - contains reference to _ID of a Story, Question and finds comments based on that

New schema idea:
StoryModel, QuestionModel - don’t contain any reference to votes
CommentsModel - contains reference to _ID of a Story, Question and finds comments based on that
VotesModel - contains reference to _ID of a Story, Question and finds votes based on that

Is this a good approach? I have no idea how fast or slow it will be in the future to retrieve multiple schemas. Currently when I retrieve a story, the vote is already included there. Via refrence I would fetch Story, Comments & Votes separately.

This may not be a problem necessarily since I’m using Apollo? I’m no DB expert though, so any feedback is very much welcome here: My main concern is to retrieve data as fast as possible obviously :slight_smile:

Ahhh… One concern that I have with this decoupled approach is that it might be harder to sort a Story if it wouldn’t contain a vote field anymore. I would then have to first sort the available votes, and based on that order sort the Stories, this might be hard to do, right?


#2

I’ve been giving this some thought… would it make sense to have a schema like this?

Each schema (Story, Question, whatever) has a voteCount to quickly retrieve the count of votes. Then, the actual votes are in it’s own votes model with id of user who voted and a reference to the document (that’s how I check if the user voted for it already)