Sunday, November 20, 2011

Introduction to Casbah - The Scala MongoDB Driver

I've been meaning to point out the sheer coolness of the Scala MongoDB driver - Casbah. Written and maintained by 10Gen's own Brendan McAdamas, it is a truly elegant way to interact with MongoDB. If you've been using the Java driver, this might be a fun way to try out some Scala.

Here are some examples, none of which will be too surprising, since they look so much like interacting with Mongo via the shell client. Really that's the nice thing about Casbah - it's much closer to using the Python driver or JavaScript shell than the Java map-style driver.

I'll demonstrate some more advanced usage in the future, but this will get you started.


//connect to a MongoDB server
val mongo = MongoConnection("anduin")

//create/connect to a collection
val coll = mongo("casbah_examples")("movies")

//drop collection
coll.dropCollection

//create some documents
val pf = MongoDBObject("title" -> "Pulp Fiction",
"director" -> "Quentin Tarantino",
"foo" -> "bar",
"actors" -> List("John Travolta", "Samuel L Jackson"),
"year" -> 1994)

val sw = MongoDBObject("title" -> "Star Wars",
"director" -> "George Lucas",
"cast" -> List("Harrison Ford", "Carrie Fisher"),
"year" -> 1977)

val fc = MongoDBObject("title" -> "Fight Club",
"director" -> "David Fincher",
"cast" -> List("Brad Pitt", "Edward Norton"),
"year" -> 1999)

//add some documents
coll += pf
coll += sw
coll += fc
val pfid = MongoDBObject("_id" -> pf.get("_id"))

//update a document
//increment a value (or set it if the value does not exist)
coll.update(pfid, $inc("likes" -> 1))

//set a value
coll.update(pfid, $set("year" -> 1994))

//remove a field
coll.update(pfid, $unset("foo"))

//add a value to an array - create it if need be
coll.update(pfid, $push("comebackKids" -> "John Travolta"))

//add a bunch of values to an array
coll.update(pfid, $pushAll("comebackKids" -> ("Bruce Willis", "Uma Thurman")))

//add to a set (only adds values that were not there already)
coll.update(pfid, $addToSet("actors") $each("John Travolta","Groucho Marx","Harpo Marx","Alyssa Milano","Bruce Willis","Uma Thurman", "Jim Carrey"))

//remove last element of an array - use -1 to remove the first element
coll.update(pfid, $pop("actors" -> 1))

//remove matching elements from a field
coll.update(pfid, $pull("actors" -> "Alyssa Milano"))

//remove more than one matching element from a field
coll.update(pfid, $pullAll("actors" -> ("Groucho Marx", "Harpo Marx")))

//rename a field
coll.update(pfid, $rename("actors" -> "cast"))

//query documents
//find one by an exact field match
coll.findOne(MongoDBObject("title" -> "Star Wars"))

//find by regex
coll.find(MongoDBObject("title" -> ".*F".r))

//leave out the ids
coll.find(MongoDBObject(),MongoDBObject("_id" -> 0))

//include only certain fields without ids
coll.find(MongoDBObject(), MongoDBObject("title" -> 1, "cast" -> 1, "_id" -> 0))

//find most recent
coll.find(MongoDBObject()).sort(MongoDBObject("year" -> -1)).limit(1)

//remove
coll.remove(MongoDBObject("title" -> "Fight Club"))

2 comments:

  1. Very nice! Good to see a good collection of Casbah usage. Brendan does an amazing job with teaching it, but where is a cheatsheet when I need it? Thank you for this. ^_^

    ReplyDelete
  2. Is there a way to atomically upsert a counter and get the new value? If I try this:

    val newGuy = MongoDBObject("collection" -> "blah", $inc("id" -> 1 ))
    counterColl.update(newGuy)

    The first line results in:
    "Error: type mismatch: Found: DBObject, required (?,?).

    ReplyDelete