Bob Ralian
Bob Ralian

Reputation: 1969

MongoDB model design for meteorjs app

I'm more used to a relational database and am having a hard time thinking about how to design my database in mongoDB, and am even more unclear when taking into account some of the special considerations of database design for meteorjs, where I understand you often prefer separate collections over embedded documents/data in order to make better use of some of the benefits you get from collections.

Let's say I want to track students progress in high school. They need to complete certain required classes each school year in order to progress to the next year (freshman, sophomore, junior, senior), and they can also complete some electives. I need to track when the students complete each requirement or elective. And the requirements may change slightly from year to year, but I need to remember for example that Johnny completed all of the freshman requirements as they existed two years ago.

So I have:

Students Requirements Electives Grades (frosh, etc.) Years

Mostly, I'm trying to think about how to set up the requirements. In a relational DB, I'd have a table of requirements, with className, grade, and year, and a table of student_requirements, that tracks the students as they complete each requirement. But I'm thinking in MongoDB/meteorjs, I'd have a model for each grade/level that gets stored with a studentID and initially instantiates with false values for each requirement, like:

{
    student: [studentID],
    class: 'freshman'
    year: 2014,
    requirements: {
        class1: false,
        class2: false
    }
}

and as the student completes a requirement, it updates like:

{
    student: [studentID],
    class: 'freshman'
    year: 2014,
    requirements: {
        class1: false,
        class2: [completionDateTime]
    }
}

So in this way, each student will collect four Requirements documents, which are somewhat dictated by their initial instantiation values. And instead of the actual requirements for each grade/year living in the database, they would essentially live in the code itself.

Some of the actions I would like to be able to support are marking off requirements across a set of students at one time, and showing a grid of users/requirements to see who needs what.

Does this sound reasonable? Or is there a better way to approach this? I'm pretty early in this application and am hoping to avoid painting myself into a corner. Any help suggestion is appreciated. Thanks! :-)

Upvotes: 0

Views: 192

Answers (1)

Michael K.
Michael K.

Reputation: 533

Currently I'm thinking about my application data design too. I've read the examples in the MongoDB manual

look up MongoDB manual data model design - docs.mongodb.org/manual/core/data-model-design/

and here -> MongoDB manual one to one relationship - docs.mongodb.org/manual/tutorial/model-embedded-one-to-one-relationships-between-documents/

(sorry I can't post more than one link at the moment in an answer)

They say:

In general, use embedded data models when:

  • you have “contains” relationships between entities.
  • you have one-to-many relationships between entities. In these relationships the “many” or child documents always appear with or are viewed in the context of the “one” or parent documents.

The normalized approach uses a reference in a document, to another document. Just like in the Meteor.js book. They create a web app which shows posts, and each post has a set of comments. They use two collections, the posts and the comments. When adding a comment it's submitted together with the post_id.

So in your example you have a students collection. And each student has to fulfill requirements? And each student has his own requirements like a post has his own comments?

Then I would handle it like they did in the book. With two collections. I think that should be the normalized approach, not the embedded.

I'm a little confused myself, so maybe you can tell me, if my answer makes sense.

Maybe you can help me too? I'm trying to make a app that manages a flea market.

Users of the app create events.

The creator of the event invites users to be cashiers for that event.

Users create lists of stuff they want to sell. Max. number of lists/sellers per event. Max. number of position on a list (25/50).

Cashiers type in the positions of those lists at the event, to track what is sold.

Event creators make billings for the sold stuff of each list, to hand out the money afterwards.

I'm confused how to set up the data design. I need Events and Lists. Do I use the normalized approach, or the embedded one?

Edit:

After reading percona.com/blog/2013/08/01/schema-design-in-mongodb-vs-schema-design-in-mysql/ I found following advice:

  • If you read people information 99% of the time, having 2 separate collections can be a good solution: it avoids keeping in memory data is almost never used (passport information) and when you need to have all information for a given person, it may be acceptable to do the join in the application.
  • Same thing if you want to display the name of people on one screen and the passport information on another screen.
  • But if you want to display all information for a given person, storing everything in the same collection (with embedding or with a flat structure) is likely to be the best solution

Upvotes: 1

Related Questions