I’ve often felt that we treat relational databases as a hammer to use with every kind of nail, screw, bolt, rivet, metric nut, and wall anchor we encounter in software development. The modern relational databases is a marvelous piece of engineering, and we have centuries of collective experience in designing, optimizing, securing, and managing them, but they just aren’t the best fit for every scenario.
The last few months I’ve been keeping an eye on the growing No-SQL movement. I’d like to make room for the No-SQL conference (nosqleast – their motto is: select fun, profit from real_world where relational=false;), but I’ll just have to wait for a debrief from Matt P. Here are a couple great blog posts for background on the No-SQL thing:
I wanted to experiment with a document oriented database myself and chose MongoDB. From the FAQ:
MongoDB is an document-oriented DBMS. Think of it as a persistent object store. It is neither a relational database, nor even "table oriented" like Amazon SimpleDB or Google BigTable. If you have used object-relational mapping layers before in your programs, you will find the Mongo interface similar to use, but faster, more powerful, and less work to set up.
I chose MongoDB because it looked easy to setup and run with.
To talk to MongoDB I used mongodb-csharp. You can either download the source as a zip file, or use a Git client like Git on Windows to clone the github repository. Sounds difficult, but Git is easy once you’ve adopted to the terminology, and as a bonus, it’s screaming fast. There is a Visual Studio solution included with the sources, so you can open it, build it, and out pops a MongoDB.Driver assembly.
Connecting to a database looks like this:
var mongo = new Mongo(); mongo.Connect(); var db = mongo.getDB("movieReviews");
I’m running MongoDB on the local machine and it’s listening on the default port with no special security settings. That simplifies the code, but also notice I can ask for a database (movieReviews), and if it doesn’t exist MongoDB will create the database for me. I don’t need to create tables or schemas or setup primary keys. It just works. I’m thinking document oriented databases are to relational databases what dynamic languages are to static languages.
The next step is to get/create a collection and start adding documents to it.
var movies = db.GetCollection("movies"); var movie = new Document(); movie["title"] = "Star Wars"; movie["releaseDate"] = DateTime.Now; movies.Insert(movie);
A collection is somewhat analogous to a table in the RDBMS world, but instead of rows and columns a collection is a bunch of documents that internally are stored in a binary JSON format (BSON). The documents can contain anything – they are schemaless, but MongoDB understands how to index and query the documents.
var spec = new Document(); spec["title"] = "Star Wars"; var starWars = movies.FindOne(spec);
With a few more abstractions (and a little bit of LINQ), document oriented databases could be a huge hit in .NET. Although, they might be better aligned with a language that runs on the DLR…
Comments
one way to do that is to embed objects within others. you can nest objects and arrays of objects which then has all the data one typically needs together in the first place. see "reaching into objects" and "schema design" pages on the mongodb.org site...
db["movies"].Insert(new Document().Append("title", "Star Wars").Append("releaseDate", DateTime.Now);
In practice that might not look so pretty but it makes sending a query a little easier.
var cursor = db["movies"].FindOne(new Document().Append("title", "Star Wars"));
As for Linq support, I recently merged in a contribution. There aren't any binaries up yet but compiling from source should work fine.
However I am having trouble trying to deserialize an object using JSON.NET
Movie m = JsonConvert.DeserializeObject<Movie>(starWars.ToString());
public class Movie
{
public Oid _id { get; set; }
public string title {get;set;}
public DateTime releaseDate { get; set; }
}
What is the Trick?
However I am having trouble trying to deserialize an object using JSON.NET
Movie m = JsonConvert.DeserializeObject<Movie>(starWars.ToString());
public class Movie
{
public Oid _id { get; set; }
public string title {get;set;}
public DateTime releaseDate { get; set; }
}
What is the Trick?
I have written some examples of how to use Json.Net to get the mappings to work as well as how to use Castle Dynamic proxy to take care of the mappings.
daniel.wertheim.se/...
//Daniel
Samus has fixed the issue with the Oid.ToString implementation in the MongoDb-driver, so it shall now give correct json. I don't know if it has reached the master-version yet.
I made a follow up to my initial post, where I just did some refac. to show how it could be used.
daniel.wertheim.se/...
//Daniel
Foo = new Foo(doc[Field1], doc[Field2]);
This is not specific to MongoDb, but applies generally when looking at C# 3 + code and applying it to C# 2.