Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

910 lines (808 sloc) 28.197 kB
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="pandoc" />
<meta name="author" content="Valtech Cours du Soir, Eric Le Merdy" />
<meta name="date" content="Feb 28, 2012" />
<link rel="stylesheet" type="text/css" media="screen, projection, print"
href="http://www.w3.org/Talks/Tools/Slidy/slidy.css" />
<script src="http://www.w3.org/Talks/Tools/Slidy/slidy.js.gz"
charset="utf-8" type="text/javascript"></script>
</head>
<body>
<div class="slide cover title">
<h1 class="title">MongoDB</h1>
<p class="author">
Valtech Cours du Soir, Eric Le Merdy
</p>
<p class="date">Feb 28, 2012</p>
</div>
<div class="slide">
<h1>What's the plan ?</h1>
<div class="figure">
<img src="00_mongodb-logo.png" /><p class="caption"></p>
</div>
<ol>
<li><p>MongoDB startup for developpers</p></li>
<li><p>Collection of documents != Relational tables</p>
<ul>
<li>Database design and Indexes</li>
</ul></li>
<li><p>Learn MongoDB query language</p></li>
<li><p>Java Driver basic usage</p></li>
<li><p>Replication</p></li>
<li><p>Map/Reduce</p></li>
</ol>
</div>
<div class="slide">
<h1>Slides...</h1>
<ul>
<li><p>...are available in a github repository:</p>
<pre><code>git clone https://ericlemerdy@github.com/ericlemerdy/mongodb-slidy-tutorial.git
firefox mongodb-slidy-tutorial/tutorial.html
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>MongoDB startup</h1>
<p><em>Have you ever installed Oracle ?</em></p>
</div>
<div class="slide">
<h1>Install the database</h1>
<ul>
<li><p>Visit the <a href="http://www.mongodb.org/downloads">Download page</a></p></li>
<li><p>Install the &quot;Production Release&quot;</p>
<ul>
<li>used 2.0.2 for this tutorial</li>
</ul></li>
</ul>
</div>
<div class="slide">
<h1>Run the database</h1>
<ul>
<li><p>MongoDB is essentially a database daemon :</p>
<pre><code>cd mongodb-linux-i686-2.0.2/bin
./mongod
</code></pre></li>
<li><p>Expected output:</p>
<pre><code>ericlemerdy@harukiya:~/mongodb-linux-i686-2.0.2/bin$ ./mongod
./mongod --help for help and startup options
Mon Feb 6 22:35:59
Mon Feb 6 22:35:59 warning: 32-bit servers don't have journaling enabled by default. Please use --journal if you want durability.
Mon Feb 6 22:35:59
Mon Feb 6 22:35:59 [initandlisten] MongoDB starting : pid=19742 port=27017 dbpath=/data/db/ 32-bit host=harukiya
...
Mon Feb 6 22:35:59 [initandlisten] db version v2.0.2, pdfile version 4.5
...
Mon Feb 6 22:35:59 [initandlisten] exception in initAndListen: 10296 dbpath (/data/db/) does not exist, terminating
...
Mon Feb 6 22:35:59 dbexit: really exiting now
ericlemerdy@harukiya:~/mongodb-linux-i686-2.0.2/bin$
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Why it shutdown ?</h1>
<ul>
<li><p>In the logs:</p>
<pre><code>dbpath (/data/db/) does not exist, terminating
</code></pre></li>
<li><p>MongoDB expects a place on disk to store the database !</p></li>
</ul>
</div>
<div class="slide">
<h1>Run the database on a specified path</h1>
<ul>
<li><p>Either</p>
<ul>
<li><p>Create the <em>/data/db</em> default directory</p></li>
<li><p>Or use the <em>dbpath</em> parameter:</p>
<pre><code>./mongod --help | grep &quot;\-\-dbpath&quot;
--dbpath arg directory for datafiles
</code></pre></li>
</ul></li>
<li><p>Create a space and restart mongo on this space</p>
<pre><code>mkdir ~/mongodatadb
./mongod --dbpath ~/mongodatadb
</code></pre></li>
<li><p>The mongod should now run successfully:</p>
<pre><code>...
Mon Feb 6 23:58:04 [initandlisten] options: { dbpath: &quot;~/mongodatadb&quot; }
Mon Feb 6 23:58:04 [websvr] admin web console waiting for connections on port 28017
Mon Feb 6 23:58:04 [initandlisten] waiting for connections on port 27017
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>The Admin Web Console ?</h1>
<ul>
<li><p><a href="http://localhost:28017">http://localhost:28017</a></p>
<div class="figure">
<img src="01_admin-web-console.png" alt="the admin web console screenshot" /><p class="caption">the admin web console screenshot</p>
</div></li>
</ul>
</div>
<div class="slide">
<h1>Does it work out-of-the-box ?</h1>
<ul>
<li><p>Click on <a href="http://localhost:28017/listDatabases?text=1">listDatabases</a></p>
<pre><code>REST is not enabled. use --rest to turn on.
check that port 28017 is secured for the network too.
</code></pre></li>
<li><p>Damn !</p></li>
</ul>
</div>
<div class="slide">
<h1>Activate rest</h1>
<ul>
<li><p>Shutdown mongod</p></li>
<li><p>Restart with <em>--rest</em> option:</p>
<pre><code>./mongod --dbpath ../../mongodatadb --rest
</code></pre></li>
<li><p>Option has been passed:</p>
<pre><code>Tue Feb 7 00:36:02 [initandlisten] options: { dbpath: &quot;../../mongodatadb&quot;, rest: true }
</code></pre></li>
<li><p>The <a href="http://localhost:28017/listDatabases?text=1">listDatabases</a> should now present an empty json list:</p>
<pre><code>{ &quot;databases&quot; : [
{ &quot;name&quot; : &quot;local&quot;,
&quot;sizeOnDisk&quot; : 1,
&quot;empty&quot; : true } ],
&quot;totalSize&quot; : 0 }
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Why JSON ?</h1>
<pre><code> { &quot;whyJSON&quot; :
{ &quot;because&quot; :
{ &quot;JSON&quot; : &quot;rocks&quot; } }
}
</code></pre>
<ul>
<li><p>MongoDB Admin Web Console uses the rest extension to easily display the results of commands</p></li>
<li><p>BSON is the binary encoded version of JSON</p></li>
<li><p>JSON is first class citizen in MongoDB</p></li>
</ul>
</div>
<div class="slide">
<h1>It is time to open a MongoDB shell !</h1>
<ul>
<li><p>Practice first, how to start a mongo client:</p>
<pre><code>./mongo
</code></pre></li>
<li><p>You should get a brand new shell</p>
<pre><code>MongoDB shell version: 2.0.2
connecting to: test
&gt;
</code></pre></li>
<li><p>This has worked because</p>
<ul>
<li><p>You started <em>mongod</em> on the default <em>27017</em> port</p></li>
<li><p><em>mongo</em> connects on a database named <em>test</em> by default</p></li>
</ul></li>
</ul>
</div>
<div class="slide">
<h1>Help</h1>
<pre><code>&gt; help
</code></pre>
<ul>
<li><p>Returns</p>
<pre><code>db.help() help on db methods
db.mycoll.help() help on collection methods
rs.help() help on replica set methods
help admin administrative help
help connect connecting to a db help
help keys key shortcuts
help misc misc things to know
help mr mapreduce
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time &gt;= 1ms
show logs show the accessible logger names
show log [name] prints out the last segment of log in memory, 'global' is default
use &lt;db_name&gt; set current database
db.foo.find() list objects in collection foo
db.foo.find( { a : 1 } ) list objects in foo where a == 1
it result of the last line evaluated; use to further iterate
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>First Achievement : MongoDB startup</h1>
<ul>
<li><p>First achievement :</p>
<p><img src="02_badge-easy.jpeg" alt="MongoDB startup is easy" /> MongoDB startup for developpers is easy !</p></li>
</ul>
</div>
<div class="slide">
<h1>Data breakdown structure</h1>
<ul>
<li><p>Document &lt; Collection &lt; Database &lt; Daemon</p></li>
<li><p>Document : JSON fragment</p>
<p>ex:</p>
<pre><code>{ &quot;mongo&quot; :
{ &quot;features&quot; : [fail-over, replication, sharding, geolocation] }
}
</code></pre></li>
<li><p>Collection : several Documents</p>
<pre><code>&gt; show collections
</code></pre></li>
<li><p>Database : several Collections</p>
<pre><code>&gt; show dbs
local (empty)
</code></pre></li>
<li><p>Daemon : several Databases (physically stored in the dbpath)</p></li>
</ul>
</div>
<div class="slide">
<h1>JSON</h1>
<ul>
<li><p>Object</p>
<pre><code>{ pairs }
</code></pre></li>
<li><p>Pair</p>
<pre><code>string : Value
</code></pre></li>
<li><p>Value</p>
<pre><code>Array, primitive values
</code></pre></li>
<li><p>Array</p>
<pre><code>[ Values ]
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Sample document</h1>
<ul>
<li><p>A JSON document :</p>
<pre><code>&gt; clipart = {
&quot;title&quot; : &quot;Code Story logo&quot;,
&quot;uploader&quot; : {
&quot;name&quot; : &quot;ericlemerdy&quot;,
&quot;href&quot; : &quot;http://openclipart.org/user-detail/ericlemerdy&quot;
},
&quot;drawn by&quot; : &quot;ericlemerdy&quot;,
&quot;created&quot; : ISODate(&quot;2012-02-08T02:05:15.401Z&quot;),
&quot;description&quot; : &quot;My contribution for the www.codestory.net logo.&quot;,
&quot;tags&quot; : [ &quot;developpers&quot;, &quot;code&quot;, &quot;computer&quot;, &quot;people&quot;, &quot;logo&quot;, &quot;public domain&quot; ],
&quot;viewed by&quot; : 236,
&quot;image&quot; : {
&quot;image/svg+xml&quot; : &quot;http://openclipart.org/people/ericlemerdy/Code_Story_Logo.svg&quot;,
&quot;image/png&quot; : &quot;http://openclipart.org/image/800px/svg_to_png/166309/Code_Story_Logo.png&quot;
}
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Relational schema</h1>
<ul>
<li><div class="figure">
<img src="03_relational-schema.png" title="Relational schema" /><p class="caption"></p>
</div>
<p>http://yuml.me/diagram/scruffy/class/[Clipart|title : String;drawn-by : String;created : Date;description : String;tags : List<String>;viewed-by : Integer], [User|name : String;href : Url], [Image|svg : Url;png : Url],[Clipart]&lt;&gt;*-uploader 1&gt;[User], [Clipart]&lt;&gt;1-image 1&gt;[Image]</p></li>
</ul>
</div>
<div class="slide">
<h1>I ♥ SQL</h1>
<ul>
<li><p>MongoDB is <strong>NOT</strong> a relational database</p></li>
<li><p>Forget what you learn about normalisation</p>
<p>This just not apply to what mongodb can do</p></li>
<li><p>In relational model, there is a promise : &quot;You can decouple schema design from applicative work (thanks to normalization)&quot;</p>
<p>That's why we get RDBMs specialists after all...</p></li>
<li><p>In MongoDB, you have to design your documents <strong>for the job</strong> that your application must do.</p></li>
</ul>
</div>
<div class="slide">
<h1>Document based schema design principles</h1>
<ul>
<li><p>Transaction is only <strong>document-based</strong></p></li>
<li><p>Storage is cheap</p></li>
<li><p><strong>Do not</strong> perform runtime relations</p>
<p><strong>Duplicate</strong> !</p>
<p>E.g. : Clipart -&gt; User</p></li>
<li><p>Think of consequences in your application :</p>
<p>When a user change its display name...</p></li>
<li><p>Does not apply to all domains where A(tomicity), C(onsistency), I(solation), D(urability) is appreciated through the entire schema.</p></li>
</ul>
</div>
<div class="slide">
<h1>Schema free ?</h1>
<ul>
<li><p>A single collection can store different &quot;types&quot; of documents</p></li>
<li><p>Manage the schema evolution by your application</p>
<p>Evolving data structure when accessing the document for exemple</p></li>
</ul>
</div>
<div class="slide">
<h1>Achievement 2 : Document schema design principles</h1>
<ul>
<li><p>Second achievement :</p>
<p><img src="04_badge-nosql.jpeg" alt="NoSQL document database != relationnal" /> Document oriented schema design is different from relational !</p></li>
<li><p>More informations : <a href="http://www.10gen.com/presentations/mongosv-2011/schema-design-principles-and-practice">10gen - MongoDB Presentations - Schema Design Principles and Practice</a></p></li>
</ul>
</div>
<div class="slide">
<h1>Are you empty ?</h1>
<ul>
<li><p>Connect to a database</p>
<pre><code>&gt; use test
switched to db test
</code></pre></li>
<li><p>Find the collections of the database</p>
<pre><code>&gt; db.getCollectionNames()
[ ]
</code></pre></li>
<li><p>The database is empty !</p></li>
</ul>
</div>
<div class="slide">
<h1>Create a collection</h1>
<ul>
<li><p>Let's create the cliparts collection.</p></li>
<li><p>There is nothing to do as long you do not insert to a first document in it :</p>
<pre><code>&gt; db.cliparts.findOne()
null
</code></pre></li>
<li><p>Does a read has created the collection ?</p>
<pre><code>&gt; db.getCollectionNames()
[ ]
</code></pre></li>
<li><p>Obviously no</p></li>
</ul>
</div>
<div class="slide">
<h1>Insert the document in the collection</h1>
<pre><code>&gt; db.cliparts.save( clipart )
</code></pre>
<ul>
<li><p>Does a write has created the collection ?</p>
<pre><code>&gt; db.getCollectionNames()
[ &quot;cliparts&quot;, &quot;system.indexes&quot; ]
</code></pre></li>
<li><p>Obviously yes</p></li>
<li>Even 2 collections !
<ul>
<li>cliparts : the collection that contains our new document</li>
<li>system.indexes : the index to allow mongo to be fast searching</li>
</ul></li>
</ul>
</div>
<div class="slide">
<h1>Counting</h1>
<ul>
<li><p>Counting elements</p>
<pre><code>&gt; db.cliparts.count()
1
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Display collection content</h1>
<ul>
<li><p>Show me the content</p>
<pre><code>&gt; db.cliparts.find()
{ &quot;_id&quot; : ObjectId(&quot;4f32ed58a1d1c40cacf43637&quot;), &quot;title&quot; : &quot;Code Story logo&quot;, (...) &quot;image/png&quot; : &quot;http://openclipart.org/image/800px/svg_to_png/166309/Code_Story_Logo.png&quot; } }
</code></pre></li>
<li><p>Formatted</p>
<pre><code>&gt; db.cliparts.findOne()
{
&quot;_id&quot; : ObjectId(&quot;4f32ed58a1d1c40cacf43637&quot;),
&quot;title&quot; : &quot;Code Story logo&quot;,
(...)
&quot;image/png&quot; : &quot;http://openclipart.org/image/800px/svg_to_png/166309/Code_Story_Logo.png&quot;
}
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>What's new ?</h1>
<ul>
<li><p>There is now an id in the object :</p>
<pre><code>&gt; db.cliparts.find( { }, { &quot;_id&quot; : 1, &quot;title&quot; : 1 } )
{ &quot;_id&quot; : ObjectId(&quot;4f32ed58a1d1c40cacf43637&quot;), &quot;title&quot; : &quot;Code Story logo&quot; }
</code></pre></li>
<li><p>Generated by the mongoDB instance</p></li>
<li><p>Must be unique per collection (and per cluser)</p>
<table>
<col width="11%" />
<col width="11%" />
<col width="5%" />
<col width="11%" />
<thead>
<tr class="header">
<th align="left">0 1 2 3</th>
<th align="left">4 5 6</th>
<th align="left">7 8</th>
<th align="left">9 10 11</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td align="left">time</td>
<td align="left">machine</td>
<td align="left">pid</td>
<td align="left">inc</td>
</tr>
</tbody>
</table></li>
<li><p>Unix time + md5 machine + process id + increment value</p></li>
</ul>
</div>
<div class="slide">
<h1>Insert another document</h1>
<ul>
<li><p>Create a second variable</p>
<pre><code>&gt; clipart2 = {
&quot;title&quot; : &quot;PC LAPTOP NOTEBOOK&quot;,
&quot;uploader&quot; : { &quot;name&quot; : &quot;Keistutis&quot;, &quot;href&quot; : &quot;http://openclipart.org/user-detail/Keistutis&quot; },
&quot;drawn by&quot; : &quot;Kostas Šliažas / Keistutis&quot;, &quot;created&quot; : ISODate(&quot;2012-02-23T09:28:36.700Z&quot;),
&quot;description&quot; : null, &quot;tags&quot; : [ &quot;PC&quot;, &quot;LAPTOP&quot;, &quot;NOTEBOOK&quot; ],
&quot;viewed by&quot; : 173, &quot;image&quot; : {
&quot;image/svg+xml&quot; : &quot;http://openclipart.org/people/Keistutis/PC.svg&quot;,
&quot;image/png&quot; : &quot;http://openclipart.org/image/800px/svg_to_png/168489/PC.png&quot;
}
}
</code></pre></li>
<li><p>Insert it twice</p>
<pre><code>&gt; db.cliparts.save( clipart2 )
&gt; delete clipart2._id # Otherwise it will be saved in the same document.
true
&gt; db.cliparts.save( clipart2 )
</code></pre></li>
<li><p>Verify</p>
<pre><code>&gt; db.cliparts.count()
3
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Edit a document</h1>
<ul>
<li><p>Extract the first uploader :</p>
<pre><code>&gt; var ericUploader = db.cliparts.findOne( { &quot;uploader.name&quot; : /eric/ } ).uploader
&gt; ericUploader
{
&quot;name&quot; : &quot;ericlemerdy&quot;,
&quot;href&quot; : &quot;http://openclipart.org/user-detail/ericlemerdy&quot;
}
</code></pre></li>
<li><p>Set it in the second document :</p>
<pre><code>&gt; db.cliparts.findAndModify( {
query : { &quot;title&quot; : &quot;PC LAPTOP NOTEBOOK&quot; }, // Query selector.
sort : {}, // Sort in case several docs are matched.
// remove : true, // To delete the document.
update : { $set : { &quot;uploader&quot; : ericUploader } }, // Modifier object.
new : false, // True to get the newly created document.
// fields : {}, // Retrieve only a sub-set of the document fields.
upsert : false // True to create object if it does not exists.
} )
{
&quot;_id&quot; : ObjectId(&quot;4f4a3df18d08530d9516afbe&quot;),
&quot;title&quot; : &quot;PC LAPTOP NOTEBOOK&quot;,
&quot;uploader&quot; : {
&quot;name&quot; : &quot;Keistutis&quot;,
&quot;href&quot; : &quot;http://openclipart.org/user-detail/Keistutis&quot;
},
(...)
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Verify document</h1>
<ul>
<li><p>Find it :</p>
<pre><code>&gt; db.cliparts.findOne( { &quot;title&quot; : /PC/, &quot;uploader.name&quot; : /eric/ } )
{
&quot;_id&quot; : ObjectId(&quot;4f4a3df18d08530d9516afbe&quot;),
&quot;created&quot; : ISODate(&quot;2012-02-23T09:28:36.700Z&quot;),
&quot;description&quot; : null,
&quot;drawn by&quot; : &quot;Kostas Šliažas / Keistutis&quot;,
&quot;image&quot; : {
&quot;image/svg+xml&quot; : &quot;http://openclipart.org/people/Keistutis/PC.svg&quot;,
&quot;image/png&quot; : &quot;http://openclipart.org/image/800px/svg_to_png/168489/PC.png&quot;
},
&quot;tags&quot; : [
&quot;PC&quot;,
&quot;LAPTOP&quot;,
&quot;NOTEBOOK&quot;
],
&quot;title&quot; : &quot;PC LAPTOP NOTEBOOK&quot;,
&quot;uploader&quot; : {
&quot;name&quot; : &quot;ericlemerdy&quot;,
&quot;href&quot; : &quot;http://openclipart.org/user-detail/ericlemerdy&quot;
},
&quot;viewed by&quot; : 173
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Distinct values</h1>
<ul>
<li><p>What are the distinct title of the cliparts collection ?</p>
<pre><code>&gt; db.cliparts.distinct(&quot;title&quot;)
[ &quot;Code Story logo&quot;, &quot;PC LAPTOP NOTEBOOK&quot; ]
</code></pre></li>
<li><p>What are the distinct tags of the cliparts collection ?</p>
<pre><code>&gt; db.cliparts.distinct(&quot;tags&quot;)
[ &quot;code&quot;, &quot;computer&quot;, &quot;developpers&quot;, &quot;logo&quot;, &quot;people&quot;, &quot;public domain&quot;, &quot;LAPTOP&quot;, &quot;NOTEBOOK&quot;, &quot;PC&quot; ]
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Explain query</h1>
<pre><code> &gt; db.cliparts.find().explain()
{
&quot;cursor&quot; : &quot;BasicCursor&quot;,
&quot;nscanned&quot; : 3,
&quot;nscannedObjects&quot; : 3,
&quot;n&quot; : 3,
&quot;millis&quot; : 0,
&quot;nYields&quot; : 0,
&quot;nChunkSkips&quot; : 0,
&quot;isMultiKey&quot; : false,
&quot;indexOnly&quot; : false,
&quot;indexBounds&quot; : {
}
}
</code></pre>
<ul>
<li><p>Traversing the entire collection</p>
<pre><code>&gt; db.cliparts.find( { &quot;uploader.name&quot;: /eric/ } ).explain()
{
&quot;cursor&quot; : &quot;BasicCursor&quot;,
&quot;nscanned&quot; : 3,
&quot;nscannedObjects&quot; : 3,
&quot;n&quot; : 2,
&quot;millis&quot; : 0,
&quot;nYields&quot; : 0,
&quot;nChunkSkips&quot; : 0,
&quot;isMultiKey&quot; : false,
&quot;indexOnly&quot; : false,
&quot;indexBounds&quot; : {
}
}
</code></pre></li>
<li><p>Same traversing but only 2 objects returned.</p></li>
</ul>
</div>
<div class="slide">
<h1>Create an index</h1>
<ul>
<li><p>Create a composite index on uploader name:</p>
<pre><code>&gt; db.cliparts.createIndex( { &quot;uploader.name&quot; : 1 } )
</code></pre></li>
<li><p>Visualize effect on search</p>
<pre><code>&gt; db.cliparts.find( { &quot;uploader.name&quot;: /eric/ } ).explain()
{
&quot;cursor&quot; : &quot;BtreeCursor uploader.name_1 multi&quot;,
&quot;nscanned&quot; : 3,
&quot;nscannedObjects&quot; : 2,
&quot;n&quot; : 2,
&quot;millis&quot; : 0,
&quot;nYields&quot; : 0,
&quot;nChunkSkips&quot; : 0,
&quot;isMultiKey&quot; : false,
&quot;indexOnly&quot; : false,
&quot;indexBounds&quot; : {
&quot;uploader.name&quot; : [
[ &quot;&quot;, { } ],
[ /eric/, /eric/ ]
]
}
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Achievement 3 : Master shell</h1>
<ul>
<li><p>Third achievement :</p>
<p><img src="05_badge-shell.jpeg" alt="Be a shell master or the mastershell" /> Be a master shell !</p></li>
<li><p>Let's move on to java !</p></li>
</ul>
</div>
<div class="slide">
<h1>Maven project</h1>
<ul>
<li><p>There is a maven project ready to import in your IDE:</p>
<pre><code>mongodb-slidy-tutorial/mongodb-java-project/
</code></pre></li>
<li><p>Un-ignore all tests and make it green !</p></li>
</ul>
</div>
<div class="slide">
<h1>Achievement 4 : Use mongoDB from java</h1>
<ul>
<li><p>Fourth achievement :</p>
<p><img src="06_badge-java.jpeg" alt="Learn MongoDB in Java" /> You have learnt how to speak MongoDB in java !</p></li>
<li><p>Now, let's replicate</p></li>
</ul>
</div>
<div class="slide">
<h1>Why replicate a database ?</h1>
<ul>
<li><p><strong>Fail-over</strong> :</p>
<p>if a node goes down the service is still up and running</p></li>
<li><p><strong>Performance</strong> :</p>
<p>if several nodes can serve the data, performance should increase</p></li>
</ul>
</div>
<div class="slide">
<h1>Replication in MongoDB</h1>
<ul>
<li><p>Implemented with : Replica Set</p></li>
<li><p>Out-of-the-box feature</p></li>
<li><p>Let's build a replica set to understand</p></li>
</ul>
</div>
<div class="slide">
<h1>I will be your master</h1>
<ol>
<li><p>Restart mongo with a replicaset name</p>
<pre><code>./mongod --dbpath ../../mongodatadb --rest --replSet valtech
(...)
Mon Feb 27 02:39:28 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)
Mon Feb 27 02:39:28 [rsStart] replSet info you may need to run replSetInitiate -- rs.initiate() in the shell -- if that is not already done
</code></pre></li>
<li><p>See the status : <a href="http://127.0.0.1:28017/_replSet">http://127.0.0.1:28017/_replSet</a></p></li>
<li><p>Initiating the replica set :</p>
<pre><code>&gt; rs.initiate()
{
&quot;info2&quot; : &quot;no configuration explicitly specified -- making one&quot;,
&quot;me&quot; : &quot;harukiya:27017&quot;,
&quot;info&quot; : &quot;Config now saved locally. Should come online in about a minute.&quot;,
&quot;ok&quot; : 1
}
</code></pre></li>
</ol>
</div>
<div class="slide">
<h1>And what is your IP address ?</h1>
<ol>
<li><p>Please join</p>
<pre><code>PRIMARY&gt; rs.add(&quot;your_ip&quot;)
{ &quot;ok&quot; : 1 }
</code></pre>
<p>On you logs:</p>
<pre><code>Mon Feb 27 03:02:47 [rsHealthPoll] replSet member harukiya:27018 is now in state STARTUP2
Mon Feb 27 03:02:49 [rsHealthPoll] replSet member harukiya:27018 is now in state RECOVERING
(...)
Mon Feb 27 03:03:04 [slaveTracking] build index local.slaves { _id: 1 }
Mon Feb 27 03:03:04 [slaveTracking] build index done 0 records 0 secs
(...)
Mon Feb 27 03:03:07 [rsHealthPoll] replSet member harukiya:27018 is now in state SECONDARY
</code></pre></li>
<li><p>An arbiter or another node must join</p>
<pre><code>PRIMARY&gt; rs.addArb(&quot;your_ip&quot;)
{ “ok” : 1 }
</code></pre></li>
</ol>
</div>
<div class="slide">
<h1>Connecting on a replica set</h1>
<ul>
<li><p>The configuration is known from the client side</p></li>
<li><p>If you try to connect to a slave:</p>
<pre><code>./mongo --host harukiya --port 27018
SECONDARY&gt; use test
switched to db test
SECONDARY&gt; db.cliparts.findOne()
Mon Feb 27 03:13:16 uncaught exception: error { &quot;$err&quot; : &quot;not master and slaveok=false&quot;, &quot;code&quot; : 13435 }
</code></pre></li>
<li><p>You can not execute queries unless you set slaveok=true :</p>
<pre><code>SECONDARY&gt; rs.slaveOk()
SECONDARY&gt; db.cliparts.findOne()
{
&quot;_id&quot; : ObjectId(&quot;4f4a3ee88d08530d9516afbf&quot;),
(...)
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Simulate a network failure</h1>
<ul>
<li><p>Shutdown master or 'stepDown'</p>
<pre><code>PRIMARY&gt; rs.stepDown()
Mon Feb 27 03:21:55 DBClientCursor::init call() failed
Mon Feb 27 03:21:55 query failed : admin.$cmd { replSetStepDown: 60.0 } to: 127.0.0.1
Mon Feb 27 03:21:55 Error: error doing query: failed shell/collection.js:151
Mon Feb 27 03:21:55 trying reconnect to 127.0.0.1
Mon Feb 27 03:21:55 reconnect 127.0.0.1 ok
SECONDARY&gt;
</code></pre></li>
<li><p>If there are enough node (a majority), there is a vote and a new primary is elected. In this case, the PRIMARY has been step down to SECONDARY. And the SECONDARY has been step up to PRIMARY. There can still have writings on database.</p></li>
</ul>
</div>
<div class="slide">
<h1>Achievement 5 : MongoDB never fails</h1>
<ul>
<li><p>Fifth achievement :</p>
<p><img src="07_badge-fail-over.jpeg" alt="MongoDB never fails" /> MongoDB will never fail !</p></li>
<li><p>Now, let's map reduce</p></li>
</ul>
</div>
<div class="slide">
<h1>Map/Reduce</h1>
<ul>
<li><p><a href="http://www.slideshare.net/nateabele/building-apps-with-mongodb">Source</a> from slide 25 to 29</p></li>
<li><p>Define the map function:</p>
<pre><code>&gt; var map = function() {
this.tags.forEach(function(t) {
emit(t, { count : 1 } );
});
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Reduce</h1>
<ul>
<li><p>Define the reduce function:</p>
<pre><code>&gt; var reduce = function(key, value) {
var count = 0;
for (var i = 0, len = value.length; i &lt; len; i++) {
count += value[i].count;
}
return { &quot;count&quot; : count };
}
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Get the result</h1>
<ul>
<li><p>Get the result object</p>
<pre><code>&gt; var result = db.cliparts.mapReduce(map, reduce, { out : &quot;mapreduceresult&quot; });
&gt; result
{
&quot;result&quot; : &quot;mapreduceresult&quot;,
&quot;timeMillis&quot; : 188,
&quot;counts&quot; : {
&quot;input&quot; : 2,
&quot;emit&quot; : 6,
&quot;reduce&quot; : 3,
&quot;output&quot; : 3
},
&quot;ok&quot; : 1,
}
</code></pre></li>
<li><p>Reading the output collection:</p>
<pre><code>&gt; db.mapreduceresult.find()
{ &quot;_id&quot; : &quot;LAPTOP&quot;, &quot;value&quot; : { &quot;count&quot; : 2 } }
{ &quot;_id&quot; : &quot;NOTEBOOK&quot;, &quot;value&quot; : { &quot;count&quot; : 2 } }
{ &quot;_id&quot; : &quot;PC&quot;, &quot;value&quot; : { &quot;count&quot; : 2 } }
</code></pre></li>
</ul>
</div>
<div class="slide">
<h1>Achievement 6 : Map/Reduce</h1>
<ul>
<li><p>Six achievement :</p>
<p><img src="08_badge-map-reduce.jpeg" alt="MongoDB map reduce" /> MongoDB Map Reduce</p></li>
</ul>
</div>
<div class="slide">
<h1>Thank you</h1>
<ul>
<li><p>hu·mon·gous adj</p>
<p>: extremely large : huge <a humongous building> <humongous amounts of money></p>
<p>perhaps alteration of huge + monstrous</p>
<p>First Known Use: circa 1967</p>
<p><img src="02_badge-easy.jpeg" /> <img src="04_badge-nosql.jpeg" /> <img src="05_badge-shell.jpeg" /> <img src="06_badge-java.jpeg" /> <img src="07_badge-fail-over.jpeg" /> <img src="08_badge-map-reduce.jpeg" /></p></li>
</ul>
</div>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.