Francis's Octopress Blog

A blogging framework for hackers.

Simple CRUD With MongoDB

Simple CRUD with MongoDB

When I meet a new technology, I like to experience it “just as it comes”. I’m happy at the command line and I like to type actual commands and see man pages before I use any wrappers or helper tools. So when I met MongoDB for the first time, I did exactly that. This post shows those first steps of creating a database, and inserting, reading, deleting and updating data.

Before we begin, you should install mongo. This is painless and for me, on ubuntu, sudo aptitude install mongodb did the trick.

Some Terminology

Here are some translations from the RDBMS equivalent wording:

  • “database” is still “database”
  • “table” becomes “collection”
  • “row” becomes “record”
  • try to forget the word “column”, we don’t have those

Let’s Begin

Creating a Database

You don’t really create a database with mongo, you just kind of start using it. Once you put something in there, it exists. I’m going to name my new database pets.

use pets

Adding Data

To do anything in mongo, you start your command with db which refers to the database you’re using. The different parts of the command are separated by dots. To insert data you use a command like db.[collection].save() and feed in the data to save. The format of the data is JSON-esque – I read JSON but I don’t really write it, however I found it became familiar pretty quickly. To insert some data, you can do:

> db.animals.save({'animal':'cat', 'name':'fluffy', 'type':'long-haired', 'owner':'Anna'});
> db.animals.save({'animal':'dog', 'type':'spaniel', 'name':'toffee', 'colour':'toffee', 'owner':'Ben'});
> db.animals.save({'owner':'Ben', 'animal':'cat', 'name':'ginger', 'collar':true});

Fetching Data

Did anything happen? We can check, using db.[collection].find() - this will give us everything in the collection, a bit like select * from [table] does in SQL.

> db.animals.find();
{ "_id" : ObjectId("4ebb8fd68f7aaffc5d287383"), "animal" : "cat", "name" : "fluffy", "type" : "long-haired", "owner" : "Anna" }
{ "_id" : ObjectId("4ebb90048f7aaffc5d287384"), "animal" : "dog", "type" : "spaniel", "name" : "toffee", "colour" : "toffee", "owner" : "Ben" }
{ "_id" : ObjectId("4ebb90768f7aaffc5d287385"), "owner" : "Ben", "animal" : "cat", "name" : "ginger", "collar" : true }

We definitely have data! We can also filter this down, the equivalent of adding a “where” clause, for example, let’s only see cats:

> db.animals.find({'animal':'cat'});
{ "_id" : ObjectId("4ebb8fd68f7aaffc5d287383"), "animal" : "cat", "name" : "fluffy", "type" : "long-haired", "owner" : "Anna" }
{ "_id" : ObjectId("4ebb90768f7aaffc5d287385"), "owner" : "Ben", "animal" : "cat", "name" : "ginger", "collar" : true }

You can add multiple constraints here, how about cats belonging to Ben?

> db.animals.find({'animal':'cat', 'owner':'Ben'});
{ "_id" : ObjectId("4ebb90768f7aaffc5d287385"), "owner" : "Ben", "animal" : "cat", "name" : "ginger", "collar" : true }

If any of the records don’t have the field you’re searching on, they won’t appear in the results. We’re not tied to a rigid structure of columns so you can just throw in whichever data seems useful at the time, and search on whatever is there. We can also search on whether we have the field at all, for example, animals where we know what colour they are:

> db.animals.find({colour: {$exists: true}});
{ "_id" : ObjectId("4ebb90048f7aaffc5d287384"), "animal" : "dog", "type" : "spaniel", "name" : "toffee", "colour" : "toffee", "owner" : "Ben" }

Updating Data

This confused me for a long time, as mongo does have an update() function, which you can use to update one or many records in a particular way. What I found I really wanted though was to use the save() method again, because if the record has an identifier that exists, mongo will update it, otherwise it will insert it as we saw above. So we can just grab a record and change it, then save it:

> db.animals.find({'animal':'dog'});
{ "_id" : ObjectId("4ebb90048f7aaffc5d287384"), "animal" : "dog", "type" : "spaniel", "name" : "toffee", "colour" : "toffee", "owner" : "Ben" }
db.animals.save({ "_id" : ObjectId("4ebb90048f7aaffc5d287384"), "animal" : "dog", "breed" : "spaniel", "name" : "toffee", "colour" : "toffee", "owner" : "Ben" });

I realised that calling a spaniel a “type” of dog would be better expressed as being a “breed”, so I simply changed that record and mongo updated it for me. The update() statement is better for working on sets of records – for example if we decide Ben should be using his Sunday name:

> db.animals.update({'owner':'Ben'}, {$set: {'owner':'Benjamin'}}, false, true);

There’s a lot going on here, so let’s look at the pieces step-by-step. The documentation describes the update function as:

db.collection.update( criteria, objNew, upsert, multi )

The first part, the criteria is the same as we would use for the find() method. The next argument is what we’re changing. I’m just setting one field to a given value, so I used the $set modifier (modifiers are an art in themselves, this post is rambling on already so I’ll write about those another day if you’re interested). The next argument is the upsert, which is whether to insert a new record if we didn’t find any matches – I want to update existing records, not insert anything, so I set this to false. Finally the multi flag tells mongo to update ALL the records it can find that match thecriteria, if this is false it will stop after one (lazy thing!).

Deleting Data

If you’ve come this far then I’m impressed, and deleting is the easy part so we’re almost there! Exactly like the find()and update() commands, we just supply a criteria to the remove() command. This could be either one of the fields, as we used already, or the object ID itself, like this:

> db.animals.remove({_id: ObjectId("4ebb90768f7aaffc5d287385")});

As with all things mongo, you won’t get any feedback about whether it worked, since most of the time we’re using this on systems so fast there isn’t time for niceties, but if you try to find() this record now, you won’t be able to.

MongoDB

There’s so much that’s exciting about mongo, the sheer size and speed of this data store, the support for map reduce, the sharding support … I could go on. However you still need to be able to have a quick word with your database and check what data it has, maybe tweak something, and I hope that these mongo examples will serve as a quick reference for anyone who needs them, including me of course! I like databases, APIs and command line, so working with mongo is kind of magical for me, are you working with it? I’d love to hear how others are getting on and what other tips I need to know, so leave a comment and share, please!