Mongo DB database modelling


#1

Hi guys,

Im fairly new to development, with less than a year of experience under the belt. I’m building a meteor app. Need some practical help with the database modelling.

App Structure:

  1. User
  2. Projects (have many Meetings, many Topics and many TRADs)
  3. Meetings (have many Topics and related to several Projects)
  4. Topics (can have many TRADs and related to multiple Projects and Meetings )
  5. TRADs = [Todos, Risks, Actions, Decisions] - each of these related to Project, Meeting, and Topic

At the moment, I have collection for Users, Projects, and Meetings (Topics and TRADs are within the Meetings collection)

Can someone give me practical example how to model the database?
I am happy to provide more info or code snippets

Many thanks,


#2

I’m new to Mongo and will be interested to hear the answer. It’s pretty straight forward in SQL.

For clarification, projects have many meetings and many topics. Meetings have many topics. Are these same topics shared between projects and meetings?

I’m confused why projects have topics. Projects have meetings. Meetings also have topics. It seems like topics may be something different in a meetings relation vs a project relation?


#3

Yes, same Topics are shared between Projects and Meetings. the reason behind is, the user creates a Project and adds Meetings and Topics to it. Simultaneously the User should be able to create a Meeting (related to a Project) and have many Topics. Also User should be able to create a Topic, and relate it to a Project.

The bottom line is, the user should be able to go into the Project, and see all the Meetings within the Project, as well as all the Topics and TRADs.


#4

Ok that makes sense. So topics belong to projects, meetings selects a topic related to that project.


#5

This is anecdotal experience talking, but I’ve almost never had luck with nesting (what end up being) top-level docs. Data structure changes and then you are stuck writing nasty migration scripts to maintain your data…


#6

thats fair point. How would you tackle it otherwise?


#7

Disclaimer: I’m not a mongo expert!

It depends. I have good luck using $push and $pull with an array of related doc ids. It ends up being more references, but also makes things like pub/sub a lot easier. Just about any time I’ve tried storing nested/arrayed data, I’ve dropped it in favor of more collections.

In your example, I’d have collections for users, projects, meetings, topics, and trads (perhaps a collection for each type, if it makes more sense). If your trads are all in the same place, one collection should work with a type field. If they are segregated based on action, I’d think about splitting them up.

There is a good read here: http://blog.mongodb.org/post/88473035333/6-rules-of-thumb-for-mongodb-schema-design-part-3

Ultimately, I think (as with most programming), you learn as you go and what was great is now in desperate need of optimization. With that in mind, I’d much rather move from embedded references to embedded docs than the reverse…


#8

@anvar I’m sorry to partially hijack your thread. If you want it back, just yell at me. :slight_smile:

But if we’re not embedding, then we simply have a collection of key value pairs with references… which is SQL. And I’m fine with that, but I does seem to take away any NoSQL advantage(s).

Do you specifically stay away from just array of objects, or does that go for embedded objects too?


#9

Hm, I’m not sure that using references takes away all of the advantages…unstructured data, horizontal scaling, etc.

I think the transition from handling data/subscriptions at the router level (IR era) to having the data/subs closer to where they are actually being used, at the template level (FR era) is relatively analogous to how I think about nesting data. If the data is truly unique to the doc, then nesting makes sense, as it’s more likely that you will want to grab the whole doc and use it.

Pubbing/Subbing to duplicate data doesn’t make sense to me, nor does having to deal with adding granularity to every pub/sub to deal with duplicate data that has been stored in the db. Plus, it’s gotten a lot easier to write reactive/complex publications that can be based around a single doc and that doc’s references.

Again, I’m no expert, just been doing mongo for ~2 years after moving from php/mysql. Things like arrays of objects stored in a doc make sense at first, but can end up being huge headaches down the road.


#10

You dont need to model the database like SQL. You can get away with making arrays in your MongDB document. use this trick a lot to save space.

so in your project document you will have an array of ids for the meetings. You can easily add and remove them.


#11

how is the data being displayed to users ?

ALWAYS try to optimize for reads vs. writes (aka its often i find the tradeoff to spend more time writing update operations / performing more work to do updates is worth the speed of reading the data…) / ive read almost all of those generic “modellng tips” guides, and theyll rarely state what i just mentioned (question mark…). good approach to modelling is to tune for how you list / search / sort long pages of docs. its not uncommon that ill maintain separate collections of the same data, structured specifically for certain views / UI requirements.

and then, in the end, dont be a lazy punk (only to ask / complain later), spend the time to write data properly so reads are efficient.