“Joins?!” in MongoDB

Inevitably, everyone who uses MongoDB has to choose between using multiple collections with id references (what I think of as self-referential) or embedded documents (with data duplicity).

See the slides / design considerations here

Separate collections require more work
  // finding a post + its comments is two queries and requires extra work
  // in your code to make it all pretty (or your ODM might do it for you)
  db.posts.find({_id: 9001});
  db.comments.find({post_id: 9001})
this also takes [a bit] more space (+1 field, +1 index)
Embedded documents are easy and fast (single seek)
// finding a post + its comments
  db.posts.find({_id: 9001});
No big differences for inserts and updates
  // separate collection insert and update
  db.comments.insert({post_id: 43, title: 'i hate unicrons', user: 'dracula'});
  db.comments.update({_id: 4949}, {$set : {title: 'i hate unicorns'}});

  // embedded document insert and update
  db.posts.update({_id: 43}, {$push: {title: 'lol @ emo vampire', user: 'paul'}})
  // this specific update requires that we store an _id with each comment
  db.posts.update( {'comments._id': 4949}, {$inc:{'comments.$.votes':1}})
documents that grow, like inserting new comments, will have a padding factor

So, separate collections are good if you need to select individual documents, need more control over querying, or have huge documents.

Embedded documents are good when you want the entire document, the document with a $slice of comments, or with no comments at all.

As a general rule, if you have a lot of “comments” or if they are large, a separate collection might be best.

Smaller and/or fewer documents tend to be a natural fit for embedding.

I tend to think of this as de-normalising as you would do in a star-schema design.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s