Skip to content

Commit

Permalink
fk_vs_ed
Browse files Browse the repository at this point in the history
  • Loading branch information
Karl Seguin committed Oct 10, 2011
1 parent 4977261 commit aeadb53
Show file tree
Hide file tree
Showing 21 changed files with 295 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
_site
1 change: 1 addition & 0 deletions _includes/fk_vs_ed/1.html
@@ -0,0 +1 @@
<div id="main">Inevitably, everyone who uses MongoDB comes to a choice between using multiple collections with id references or embedded documents</div>
4 changes: 4 additions & 0 deletions _includes/fk_vs_ed/10.html
@@ -0,0 +1,4 @@
<div id="main">
<p>So, separate collections are good if you need to select individual documents, need more control over querying.</p>
<p>Embedded documents are good when you want the entire document, the document with a $slice of comments, or with no comments at all</p>
</div>
6 changes: 6 additions & 0 deletions _includes/fk_vs_ed/11.html
@@ -0,0 +1,6 @@
<div id="main">
<p>As a general rule, if you have a lot of "comments" or if they are large, a separate collection might be best.</p>
<p>Smaller documents tend to be a natural fit for embedding</p>
</div>

<div class="note">Virtual collection + positional field selection are relevant upcoming[ish] features</div>
1 change: 1 addition & 0 deletions _includes/fk_vs_ed/12.html
@@ -0,0 +1 @@
<div id="main">Remember, you can always change your mind. Trying each out is the best way to learn.</div>
20 changes: 20 additions & 0 deletions _includes/fk_vs_ed/2.html
@@ -0,0 +1,20 @@
<h2>Use separate collections</h2>
<pre>
&gt; db.posts.find();
{_id: 1, title: 'unicorns are awesome', ...}

&gt; db.comments.find();
{_id: 1, post_id: 1, title: 'i agree', ...}
{_id: 2, post_id: 1, title: 'they kill vampires too!', ...}
</pre>

<div id="or">- or -</div>

<h2>Use embedded documents</h2>
<pre>
&gt; db.posts.find();
{_id: 1, title: 'unicorns are awesome', ..., comments: [
{title: 'i agree', ...},
{title: 'they kill vampires too!', ...}
]}
</pre>
5 changes: 5 additions & 0 deletions _includes/fk_vs_ed/3.html
@@ -0,0 +1,5 @@
<div id="main">
Don't worry, this means that <em>you get it</em>
</div>

<div class="note">Both solutions have their strengths and weaknesses. Learn to use both</div>
14 changes: 14 additions & 0 deletions _includes/fk_vs_ed/4.html
@@ -0,0 +1,14 @@
<div id="main">Separate collections offer the greatest querying flexibility</div>

<pre>
// sort comments however you want
> db.comments.find({post_id: 3}).sort({votes: -1}).limit(5)

// pull out one or more specific comment(s)
> db.comments.find({post_id: 3, user: 'leto'})

// get a all of a user's comments joining the posts to get the title
> var comments = db.comments.find({user: 'leto'}, {post_id: true, votes: true})
> var postIds = comments.map(function(c) { return c.post_id; });
> db.posts.find({_id: {$in: postIds}}, {title: true});
</pre>
15 changes: 15 additions & 0 deletions _includes/fk_vs_ed/5.html
@@ -0,0 +1,15 @@
<div id="main">Selecting embedded documents is more limited</div>

<pre>
// you can select a range (useful for paging)
// but can't sort, so you are limited to the insertion order
> db.posts.find({_id: 3}, {comments: {$slice: [0, 5]}})

// you can select the post without any comments also
> db.posts.find({_id: 54}, {comments: -1})

// you <em>can't</em> use the update's position operator ($) for field selections
> db.posts.find({'comments.user': 'leto'}, {title: 1, 'comments.$': 1})
</pre>

<div class="note">(there are two separate features, currently in planning/development, which should address this)</div>
3 changes: 3 additions & 0 deletions _includes/fk_vs_ed/6.html
@@ -0,0 +1,3 @@
<div id="main">A document, including all its embedded documents and arrays, cannot exceed 16MB</div>

<div class="note">Don't freak out, The Complete Works of William Shakespeare is around 5.5MB</div>
10 changes: 10 additions & 0 deletions _includes/fk_vs_ed/7.html
@@ -0,0 +1,10 @@
<div id="main">Separate collections require more work</div>

<pre>
// finding a post + its comments is two queries and require 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})
</pre>

<div class="note">this also takes [a bit] more space (+1 field, +1 index)</div>
6 changes: 6 additions & 0 deletions _includes/fk_vs_ed/8.html
@@ -0,0 +1,6 @@
<div id="main">Embedded documents are easy and fast (single seek)</div>

<pre>
// finding a post + its comments
> db.posts.find({_id: 9001});
</pre>
14 changes: 14 additions & 0 deletions _includes/fk_vs_ed/9.html
@@ -0,0 +1,14 @@
<div id="main">No big differences for inserts and updates</div>

<pre>
// separate collection insert and update
> db.comments.insert({post_id: 43, title: 'i hate unicrons', user: 'dracula'});
> db.comments.update({_id: 4949}, {$set : {tiltle: '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}})
</pre>

<div class="note">documents that grow, like inserting new comments, will have a <a href="/whats-a-padding-factor">padding factor</a></div>
23 changes: 23 additions & 0 deletions _layouts/bare.html
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ page.title }}</title>
<link href="/assets/css/main.css" rel="stylesheet" type="text/css">
{% for font in page.fonts %}
<link href="http://fonts.googleapis.com/css?family={{ font }}" rel="stylesheet" type="text/css">
{% endfor %}
{% if page.css %}<link href="styles.css" rel="stylesheet" type="text/css">{% endif %}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" type="text/javascript"></script>
<script src="/assets/js/main.js" type="text/javascript"></script>
{% if page.multi %}<script src="/assets/js/multi.js" type="text/javascript"></script>{% endif %}
</head>
<body>
<div id="page">{{ content }}</div>
<img src="/assets/i/leaf.png" id="leaf" />
<div id="footer">
<a href="https://github.com/karlseguin/mongohelp">fork it</a>
<a href="http://openmymind.net">openmymind.net</a>
</div>
</body>
</html>

20 changes: 20 additions & 0 deletions assets/css/main.css
@@ -0,0 +1,20 @@
*{padding:0;margin:0;border:none;}
body{font-family:verdana;background:#222;color:#fff;}
a{text-decoration:none;color:#c35617;}

#page a:hover{text-decoration:underline;}
#multi{display:none;}
#leaf{position:fixed;bottom:0;width:23px;height:50px;right:50px;cursor:pointer}
#footer{height:35px;width:100%;position:absolute;bottom:0;display:none;text-align:right;}
#footer a{color:#fff;padding:2px 0;margin-right:40px;text-decoration:none;border:2px solid transparent;}
#footer a:hover{border-bottom-color:#fff}

#next, #prev{position:absolute;top:0;right:0;height:100%;width:50px;color:#222;font-size:32px;}
#prev{left:0;}
#next:hover, #prev:hover {color:#111;background:#333;text-shadow:0 0 20px #fff;}
#next:hover{border-left:1px solid #444;}
#prev:hover{border-right:1px solid #444;}
#next span, #prev span{position:absolute;top:50%;width:100%;text-align:center;}
#next span:after{content:'\276f'}
#prev span:after{content:'\276e'}
#pager{position:fixed;bottom:25px;left:25px;color:#888;font-size:80%;}
Binary file added assets/i/leaf.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions assets/js/main.js
@@ -0,0 +1,30 @@
$(document).ready(function() {
//footer code
var $footer = $('#footer');
var $leaf = $('#leaf').click(function() {
if ($footer.visible()) { hideFooter(); }
else { showFooter(); }
});
function hideFooter() {
$footer.slideUp();
$leaf.animate({bottom: '0px'}, 'normal');
}
function showFooter() {
$footer.slideDown();
$leaf.animate({bottom: '45px'}, 'normal');
}
$(document).keydown(function(e) {
if (e.keyCode == 27 && $footer.visible()) {
hideFooter();
}
});

$('pre').each(function(i, pre) {
var $pre = $(pre);
$pre.html($pre.html().replace(/( *\/\/.*)/g, '<span class="comment">$1</span>'))
})
});

$.fn.visible = function() {
return this.is(':visible');
};
84 changes: 84 additions & 0 deletions assets/js/multi.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions foreign-keys-versus-embedded-documents/index.html
@@ -0,0 +1,22 @@
---
layout: bare
title: Foreign Keys vs Embedded Documents
css: true
multi: true
fonts: [Chivo]
---

<div id="multi">
<div>{% include fk_vs_ed/1.html %}</div>
<div>{% include fk_vs_ed/2.html %}</div>
<div>{% include fk_vs_ed/3.html %}</div>
<div>{% include fk_vs_ed/4.html %}</div>
<div>{% include fk_vs_ed/5.html %}</div>
<div>{% include fk_vs_ed/6.html %}</div>
<div>{% include fk_vs_ed/7.html %}</div>
<div>{% include fk_vs_ed/8.html %}</div>
<div>{% include fk_vs_ed/9.html %}</div>
<div>{% include fk_vs_ed/10.html %}</div>
<div>{% include fk_vs_ed/11.html %}</div>
<div>{% include fk_vs_ed/12.html %}</div>
</div>
12 changes: 12 additions & 0 deletions foreign-keys-versus-embedded-documents/styles.css
@@ -0,0 +1,12 @@
h2{color:#ddd;font-weight:normal;margin-bottom:10px;}
p{margin-bottom:35px;}
pre{line-height:26px;margin-bottom:50px;}
pre .comment{color:#5a5;}

#page{font-family:Chivo,verdana;width:960px;margin:100px auto;font-size:16px;}
#main{font-size:32px;text-align:center;line-height:50px;margin-bottom:50px;}
body.first #main, body.last #main{padding:50px 0;border:solid #444;border-width:6px 0;}
body.first #main:first-letter, body.last #main:first-letter{font-size:75px;}
#or{font-size:50px;text-align:center;margin-bottom:50px;color:#ccc;text-shadow:0 0 3px #000;}

.note{font-size:20px;color:#ccc;text-align:right;margin-top:10px;font-style:italic;}
5 changes: 4 additions & 1 deletion index.html
@@ -1 +1,4 @@
My GitHub Page
---
layout: bare
title: MongoDB Help
---

0 comments on commit aeadb53

Please sign in to comment.