This is the first post in a small series about RavenDB – a document database in .NET. I will try to touch the same areas as I did in my series on MongoDB, possibly comparing the two where I see fit.
Now, first – let’s see if the raven can fly…
Getting started
I am extremely happy to see that Ayende has created the same installation experience as I got with MongoDB… i.e., to get the server running, perform the following steps (assuming the .NET 4 framework is installed on your system):
- Grab a ZIP with the lastest build here
- Unzip somewhere
- Go to /Server and run Raven.Server.exe
– and now the RavenDB server will be running on localhost:8080. That was easy. Now, try visiting http://localhost:8080 in your browser – now you should see the administration interface of RavenDB.
By the way, have you ever tried installing Microsoft SQL Server? Shudder!! ๐
Connecting with the .NET client
I’m old school, so I am still using Visual Studio 2008. If you’re old school like me, add a reference to /Client-3.5/Raven.Client-3.5.dll – otherwise add a reference to /Client/Raven.Client.Lightweight.dll.
Now, to open a connection, do this:
|
var documentStore = new DocumentStore {Url = "http://localhost:8080"}; documentStore.Initialize(); using (var session = documentStore.OpenSession()) { // .... } |
– and then store the
DocumentStore as a singleton in your program.
Inserting a document
Now, let’s try inserting a document… say we have a POCO model representation of a person that looks like this (allowing
Address to be either
DomesticAddress or
ForeignAddress):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
public class Person { public string Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public Address Address { get; set; } } public abstract class Address { public abstract string ToString(string separator); } public class ForeignAddress : Address { public string[] AddressLines { get; set; } public override string ToString(string separator) { return string.Join(separator, AddressLines ?? new string[0]); } } public class DomesticAddress : Address { public string Street { get; set; } public string HouseNumber { get; set; } public string PostalCode { get; set; } public string City { get; set; } public override string ToString(string separator) { return string.Join(separator, new[] { string.Format("{0} {1}", Street, HouseNumber), string.Format("{0} {1}", PostalCode, City) }); } } |
Then, do this:
|
using (var session = documentStore.OpenSession()) { session.Store(new Person { FirstName = "Mogens Heller", LastName = "Grabe", Address = new DomesticAddress { Street = "Torsmark", HouseNumber = "4", PostalCode = "8700", City = "Horsens" } }); session.SaveChanges(); } |
Now, let’s visit http://localhost:8080/raven/documents.html in the browser… it will probably look something like this:
As you can see, RavenDB stores all documents in a single collection. Right now, there’s one person in there, and then there’s a document that RavenDB uses to generate integer IDs based on the hi-lo-algorithm. Rob Ashton has an explanation here on the design decisions made for this particular piece of RavenDB.
I like this particular decision, because it makes for some really nice human-readable, human-typeable IDs.
Note how the ID of the document is
people/1 – RavenDB is smart enough to pluralize most names, which is pretty cool. Let’s click the document to see what’s in it:
Note also how RavenDB puts type information in the document, allowing the proper subtype to be deserialized. Now, let’s try this out:
|
using (var session = documentStore.OpenSession()) { var me = session.Load<Person>("people/1"); Console.WriteLine(@"{0} {1} {2}", me.FirstName, me.LastName, me.Address); } |
– which results in the following console output:
|
Loading document [people/1] from http://localhost:8080 Mogens Heller Grabe Torsmark 4 8700 Horsens |
How cool is that?! (pretty cool, actually…)
Note that the pretty UI is based on the actual RavenDB interface to the world, which is REST-based. That means we can go to a DOS prompt and do this:
|
C:\>curl -X GET localhost:8080/docs/people/1 {"FirstName":"Mogens Heller","LastName":"Grabe","Address":{"$type":"raventjek.Class1+DomesticAddress, raventjek","Street":"Torsmark","HouseNumber":"4","PostalCode":"8700","City":"Horsens"}} |
Now, that was a short dive into storing documents and retrieving them again by ID. We need to do more than that, though – otherwise we would have been content using a simple key/value-store. Therefore, in the next post, I will take a look at querying…