How to organize Mongo collections of a users system

Problem

I'm new with noSQL databases(MongoDB) and I'm not sure how to organize collections. I have an users system where every user have:

  • _id
  • Username
  • Password
  • ... (more basic data)
  • Friends
  • Reputation points
  • History of the reputation points
  • Notifications
  • User groups that has joined

Basic data are stored in the collection users normally, but I'm not sure how to store the complex data like the list of friends.

Should I store friends like an array of _id in every user object (within users collection) or should I create a new collection to store only friends? If I create this new collection, it should be like an _id of user and an array of its friends, or pairs like user => friend _id.

Same for notifications and history. It's the same problem I have with friends, but the size of the arrays in these cases may be much larger, so the idea of using a new collection is stronger.

Problem courtesy of: Miguel

Solution

I assume that you are creating some kind of social network where the friends of each user are other users.

Collections which represent only relations between documents should generally be avoided in MongoDB. In a relational database you would use these to join tables, but MongoDB does not support joins.

You should add an array of friends to each user. That's the usual way of implementing a many-to-many relationship in MongoDB. But because you have a relation and not an aggregation (the friends aren't owned by the user - they exist independently) you shouldn't put the whole friend objects into these arrays. Instead of that you should use an unique identifier which can be used to find the friends in the user collection. This can be either the _id of the friend, a DBRef or the name of the friend (only when these are unique and indexed). The latter solution would allow you to get a readable list of the friends of a user without requesting all the referenced documents.

A counter-example where it would make sense to store the whole objects in the user document could be the notifications. A notification is sent to an individual user. Without the user, the notification is meaningless. You will never need a notification without already having the user who is receiving it. When a user is deleted, it's notifications can be deleted with it. So you can store it right in the user document.

Solution courtesy of: Philipp

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.