By Internet standards, MongoDB is a venerable NoSQL database.
First introduced in 2009, it was designed as a scalable document storage
engine. In Mongo, we don’t work with tables and rows, we work with collections and documents. Documents contain JSON/BSON hashes, so any data that can be represented as a hash can be stored in Mongo. Mongo is a schemaless database, meaning there’s no requirements nor enforcement about the structure of the data in a document.
Mongo is able to handle massive data sets quickly and efficiently,
and is used by many big data organizations, including Foursquare,
bit.ly, and CERN for collecting Large Hadron Collider data.
Installation
This is fairly straight forward using homebrew.
1
$brewinstallmongodb
When it finishes, it will print out some information on setting up
Mongo to start whenever you start your computer. I’m not a huge fan of
that. Here’s what I use:
1
$brewservicesstartmongodb
..and to stop it:
1
$brewservicesstopmongodb
Mongo and Rails
Let’s make a new Rails application, but specify that we do NOT want Active Record installed.
1
$railsnewmongo-people--skip-active-record
cd into the project, and edit the Gemfile, add this line:
Just as when using a relational DB such as SQLite, Postgres, or
MySQL, we need a configuration file. Mongoid installs a custom Rails
generator for us. Run:
1
$railsgeneratemongoid:config
Open up the file it creates, located at config/mongoid.yml and take a look. Take note of the different options we could configure. Don’t make any changes at this time; its enough to just take a look at what the generator created on our behalf.
At this point, I like to run rails s and make sure the
server starts, that everything is all hunkey-dorey. Once you’ve checked
in a browser that Rails is at least starting up correctly, let’s make a
new git repo and check in what we’ve got so far.
Let’s get started. Since this is a demonstration, let’s cheat a
little bit and use Rails’ scaffolding generators to get us started.
1
$railsgeneratescaffoldpersonnamestreetcitystate
Use git status to see what the command generated. It should all look pretty normal.. but let’s take a look at the model it generated.
Quite different! MongoDB doesn’t have a database schema, so no
database migrations are needed. If we want a new field, we could just
declare one in the model and add it to our views. Migrations are
occasionally used, but they’re for data migration or transformation, not
changing the structure of the database.
Let’s fire up our Rails server and visit the scaffolded route (at http://localhost:3000/people)
There we see the vanilla Rails CRUD forms. Let’s add a person.. and
look at the URL in the show page – weird! We’re used to seeing
incrementing IDs created for us by the database. Each row that is added
to the table increments the row counter by exactly 1, so we might say
that each row has a locally unique sequential identifier.
MongoDB uses these weird looking hashes of alphanumerics like “532e2ba7546f6c30aa000000”. This Object ID is always 12 bytes, composed of a timestamp, client machine id, client process id, and a 3-byte incremented counter.
Documents
Let’s take a look at what a document looks like.
You may have seen command line interfaces for PostgreSQL, so it
shouldn’t come as a shock that MongoDB offers one as well. In a terminal
window:
1
$mongomongo_people_development
Note that I found the name of our database by looking at config/mongoid.yml.
Mongo uses its own special command language for working with its data. If you get stuck, just type help.
First, let’s take a look at the collections in this database.
1234
>showcollectionspeoplesystem.indexes>
To find a record, the format is db.[collection].find()
12345
>db.people.find(){"_id":ObjectId("532e2ba7546f6c30aa000000"),"name":"Kerri Miller","street":"123 Main Street","city":"SEATTLE","state":"WA"}>db.people.find({"state":"WA"}){"_id":ObjectId("532e2ba7546f6c30aa000000"),"name":"Kerri Miller","street":"123 Main Street","city":"SEATTLE","state":"WA"}>
Note that the first command returned ALL documents in the collection,
we just happened to only have one document, so that’s all that was
returned.
Remember when I said that MongoDB stores everything as JSON? Mongo actually uses JavaScript here in the command line.
MongoDB is designed to be highly-scalable and flexible, but remain
familiar enough that application developers could use it easily. Working
with Mongo is mostly the same as working with a traditional RDBMS
(except for being unable to do server-side JOINs between two sets of
data..)
Because it can’t do server-side JOINs, the relationships between
different objects (Users have Posts, Posts have Comments, Comments have
Users) can be tricky, as you need to set up those relationships in the
model.
Why not MongoDB?
How MongoDB encourages denormalization of schemas (by not having any)
might be a little too much for some to swallow. Some developers find
the cold, hard constraints of a relational database reassuring.
Although sometimes restrictive, a database schema and the restraints
it places on our data can be reassuring and useful. While MongoDB offers
a huge increase in scalability and speed of record retrieval, its
inability to relate documents from 2 different collections — the key
strength of a RDBMS — makes it often not the best case for a
CRUD-focused web application.
Because MongoDB is focused on large datasets, it works best in large clusters, which can be a pain to design and manage.
Comments
Post a Comment