Giter Site home page Giter Site logo

Mongo schema design about pullup HOT 3 CLOSED

larvalabs avatar larvalabs commented on June 16, 2024
Mongo schema design

from pullup.

Comments (3)

treygriffith avatar treygriffith commented on June 16, 2024

Hey @marco-fiset, I created the separate collections for Votes and Comments, so I'm probably the best one to answer as to the reasoning why. (and don't worry, I'm not offended).

The way the database is designed now is really more of a relational design, and doesn't take much advantage of MongoDB's document-based design. However, I've found that the document-based databases are the most useful when each document is self-contained. It starts to break down when the connections between documents become important, as is the case with both Votes and Comments. Specific reasoning behind each one is below.

I separated Comments into their own collection for two reasons:

  1. It will likely be useful to query comments by author to create a page of submitted comments (like on HN)
  2. The comments for any single article might grow fairly large, and we probably won't want to retrieve all of the comments for every article just to build the front page. You can exclude the comments from the query, but then you'd have to do a separate count query anyway.

I separated Votes into their own collection because of disadvantages of the other two options (or at least the only other two options I thought of).

  1. Store a vote count on the news item
    • If a simple vote count is stored on the news item, the user profile will have to include every news item that a user has voted for so that we can prevent voting for an item more than once. This keeps the data in two places, which is prone to problems, and is by it's nature a non-atomic operation.
  2. Store all of the voters on the news item in an array
    This has multiple drawbacks:
    • It boosts the size of the news items on the front page (a similar, although less serious problem than the comments problem above)
    • To avoid conflicts when users simultaneously vote for an item you'd have to employ Mongo's $addToSet or $push operator, which means that you can't use subdocuments (since each subdoc would have a unique _id). Without subdocuments, the votes can't have any metadata, like the magnitude or direction of a vote (i.e. a downvote). Without that metadata, you'd need an entirely new array for each change (e.g. a downvotes array and an upvotes array).

I'm definitely open to discussing the alternatives, especially for Votes, but the pro's of separate collections seemed to outweigh the cons to me, with the added benefit of being familiar to users coming from a relational DB background.

For reference, this reddit thread has over 10,000 comments. And the most popular HN post got over 4,000 upvotes.

from pullup.

treygriffith avatar treygriffith commented on June 16, 2024

Oh, and something I forgot to mention is that nested comments (#153) would result in a pretty deeply nested comments subdocuments / vote arrays.

from pullup.

marcofiset avatar marcofiset commented on June 16, 2024

@treygriffith Thanks for the clarification, I see you gave it a lot more thought than I did! It makes a lot more sense to me now.

I exactly thought the same thing about multi-level comment nesting when I looked at the new issues this morning and saw #153.

from pullup.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.