<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/nodbi-the-nosql-database-connector/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://ropensci.org/technotes/2018/01/25/nodbi/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<h2>DBI</h2>
<p>What is DBI? <a rel="nofollow" href="https://cran.r-project.org/web/packages/DBI/" target="_blank">DBI</a> is an R package. It defines an interface to relational database management systems (R/DBMS) that other R packages build upon to interact with a specific relational database, such as <a rel="nofollow" href="https://sqlite.org/" target="_blank">SQLite</a> or <a rel="nofollow" href="https://www.postgresql.org/" target="_blank">PostgreSQL</a>.</p>
<h2>NoSQL</h2>
<p><a rel="nofollow" href="http://nosql-database.org/" target="_blank">NoSQL databases</a> are a very broad class of database that can include document databases such as CouchDB and MongoDB, key-value stores such as Redis, and more. They are generally not row-column relational stores though, though can include that. NoSQL is often thought of now as “not only SQL”.</p>
<p>You can imagine how it is relatively straight-forward to create a common interace to row-column oriented databases, and DBI is great for that.</p>
<p>However, a common interface to NoSQL datbases is a bit harder to wrap your head around for various reasons. One of the most obvious of which is that they don’t share a fundamental data structure like R/DMBS do.</p>
<h2>A sort of DBI for NoSQL</h2>
<p><a rel="nofollow" href="https://github.com/ropensci/nodbi" target="_blank">nodbi</a> (the <code>no</code> for “N” and “O” in “NoSQL”) was started nearly 3 years ago during the <a rel="nofollow" href="https://github.com/ropensci/unconf15" target="_blank">2015 rOpenSci Unconference</a> on <a rel="nofollow" href="https://github.com/ropensci/nodbi/commits/29340320b28f13e942ae177886d3d6b87366c4c2" target="_blank">26 March</a> together with <a rel="nofollow" href="https://github.com/richfitz" target="_blank">Rich FitzJohn</a> and <a rel="nofollow" href="https://github.com/jeroen" target="_blank">Jeroen Ooms</a>. We’ve worked on it here and there, but it hasn’t seen any commits in nearly a year.</p>
<p>Given the success of <a rel="nofollow" href="https://cran.r-project.org/web/packages/dplyr/" target="_blank">dplyr</a> it goes to reason that something that can abstract away the details for NoSQL databases – for a subset of the most common operations – could prove to be very useful.</p>
<p>nodbi takes a different approach than DBI (thus the “sort of” in this section title) in that instead of package X for database Y importing DBI and extending its methods, nodbi provides the connection objects to various databases, and a set of common methods for interacting with those databases. Whereas DBI doesn’t import or depend in any way on packages for individual databases, nodbi has packages for individual databases in Suggests. That is to say, nodbi can be installed and loaded without any specific database package, but to use any one database (e.g., Mongo) you need to install the package for that database (i.e., <a rel="nofollow" href="https://cran.r-project.org/web/packages/mongolite/" target="_blank">mongolite</a>). Because database packages in nodbi are in Suggests, you can pick and choose the packages you want to have installed – and forget about the others.</p>
<p>Check out the package <a rel="nofollow" href="https://github.com/ropensci/nodbi" target="_blank">on GitHub</a>.</p>
<h2>data.frame’s</h2>
<p>Thus far, we’ve built nodbi around data.frame’s. That is, we’re focusing on the data.frame use case as it’s very common that R users are dealing solely with data.frame’s in their analysis pipelines.</p>
<p>Let us know if you have a strong need for lists or vectors, etc. in nodbi.</p>
<h2>supported databases</h2>
<p>Connection functions to each database follow the pattern <code>src_</code> following the pattern used by <code>dplyr</code></p>
<ul>
<li>MongoDB: <code>src_mongo</code></li>
<li>Redis: <code>src_redis</code></li>
<li>CouchDB: <code>src_couchdb</code></li>
<li>Elasticsvearch: <code>src_elastic</code></li>
<li>Etcd: <code>src_etcd</code></li>
</ul>
<p>The details of connecting to different databases vary as you’d imagine, but what’s returned from <code>src_</code> functions can be passed to any of the below methods (for the most part).</p>
<h2>supported methods</h2>
<ul>
<li>create (<code>docdb_create</code>): Create an object</li>
<li>get (<code>docdb_get</code>): Get an object</li>
<li>delete (<code>docdb_delete</code>): Delete an object</li>
<li>update (<code>docdb_update</code>): Update an object. CouchDB only for now</li>
</ul>
<p>Operations in nodbi follow a key-value pattern. That is, an object (read: data.frame) is stored in your choice of database with a key (read: character string). Not every operation above needs both the key and value – for example, deleting an object only requires the key.</p>
<p>Internally, a key maps differently to Redis vs. Mongo vs. CouchDB, etc. But the point is that we’re abstracting away the details so that the user can focus on getting things done faster.</p>
<h2>Setup</h2>
<p>You’ll need to start up the database you want to work with if it’s not started already. Let’s work with Mongo for this blog post.</p>
<p>Check out the <a rel="nofollow" href="https://jeroen.github.io/mongolite/" target="_blank">mongolite book</a> for details on installing MongoDB</p>
<p>Start up mongo on your cli (i.e., shell or terminal)</p>
<pre><code>mongod # or sudo mongod
</code></pre>
<p>Install database packages</p>
<pre><code>install.packages(c(&quot;sofa&quot;, &quot;etseed&quot;, &quot;elastic&quot;, &quot;mongolite&quot;, &quot;redux&quot;))
</code></pre>
<p>Install nodbi</p>
<pre><code>devtools::install_github(&quot;ropensci/nodbi&quot;)
</code></pre>
<pre><code>library(nodbi)
</code></pre>
<h2>Examples</h2>
<p>Connect to Mongo with <code>src_mongo</code></p>
<pre><code>(src &lt;- src_mongo(verbose = FALSE))
#> MongoDB 3.6.2 (uptime: 3017s)
#> URL: leothelion.local/test
</code></pre>
<p>With the connection object you can access the name of the Mongo database</p>
<pre><code>src$db
#> [1] &quot;test&quot;
</code></pre>
<p>And the connection <code>mongolite</code> connection object</p>
<pre><code>src$con
#> </code></pre>