2012/08/07

Playing with Ravens

Right now, I have a few ideas for pet projects I plan to work on over the next months. More on that in another post, but most of them include a data store other than an RDBMS.

Being on .Net, I have chosen to use RavenDB. Now it’s not that easy for an old SQL boy like me, so I started playing with it and making some notes here.

Getting the software

Ayende said on the mailing list, the current unstable version will be ready in a few month. Realistically, I won’t finish my project before this upcoming version will be out of support Winking smile, so I can go for unstable confidently. Even more when I read the standard reply on the list for bug reports: "Test will pass in the next build."

Installing

Simple: Unzip build to directory, and call start.cmd. This will even work by clicking on it since a new window pops up by default. However will be a UAC popup as the server calls netsh to grant rights for http.sys, but it requests this only once.

First steps

In the beginning, there was nothing. Not even a database, so let’s create a sample database. Did I mention I love it when batteries are included?

image

After creating the sample data, let’s take a look at the contents:

image

Ok, so we can view and inspect and update entities. Now, can we also do queries?

Querying data

Now where are the queries? It turns out (with a little bit of clicking around) that they are filed under indexes.image

So let’s start with a dynamic query, which is the equivalent to ad-hoc SQL queries on an RDBMS. Raven uses Lucene query syntax, which is documented on the Lucene tutorial. Now let’s look what albums are of my taste here:

image

Ok, that’s cool. We have everything we need on the page: Query, results, statistics. However, the result data displayed is not what I wanted. So I hit “Show fields”, hoping to get some dialog for choosing fields. But when I have it activated, Raven only displays the IDs of the documents.

Well, you can change it by right clicking the column titles:

image

image

image

Ok, so we can query the data ad-hoc without writing a map-reduce-function.

Indexes

Back on the index page, the query I just executed is displayed as an temporary index:

image

Ok, let’s edit this, so we can get the same result as before:

image

Looks like C# Linq, so how about this:

image

That looks promising and the index can actually be queried, but the studio shows the same strange result as above:

image

Eventually I will find that out… some day…

More Indexing

Now let’s go for a more demanding example. I want to know how many albums each Artist has published here. Luckily, there is already an artist index we can start with:

image

It’s actually quite easy, though I needed some minutes to get it right:

image

You should keep the following in mind:

  • Don’t put the Albums count into the group
  • Use Extension Methods for aggregations
  • Everything is case sensitive!

Now we nearly got it:

image

One more thing before I send the ravens back to their nest. I want only Artists that have between 10 and 20 albums published in the database. The default Lucene Syntax could be: Albums: [10 TO 20], but

image

Lucene searches lexicographically, so we need a special, yet nearly undocumented syntax, that I found in an example in the RavenDB docs:

image

Conclusion

Now I feel somewhat familiar with the studio, so next time let’s see how we can query this values from within code.

2012/01/02

To How Many Bounded Contexts Does Your Model Belong To?

Yesterday I have read this blog post by Chad Myers. I agree with him – more or less – on the current state of web frameworks, but I have something to add:

More pants Bras on the head

Chad emphasizes the …Model. Every web framework since WebForms emphasizes the …Model. There is MVC, there is MVVM and MVP. Everywhere there is a …Model. But what is the …Model? Let’s take a closer look.

What is a model?

A model is an abstraction. If I have something complex, something too complex to handle, I create a model that allows me to handle it. Looking at typical web applications, I ask myself: What is so complex here that I need an abstraction layer or even two?

To pull the data from the data store, we use a model. We put bras on the head and chant the rhyme of “Persistence Ignorance”. Then we build another model, now called view model that consists of a projection of the “real model” along with some specialized collections with one or two extra properties, because using more than one object to pass in the view is the deadly sin of web programming.

All this to put a simple SELECT TITLE,AUTHOR FROM POSTS on a web page? You must be kidding.

Complex Applications

Ok, not all applications are tutorial like. Let’s have a look at an application that deserves a model: Imagine something more complex, like Eric Evans shipping sample in Domain Driven Design. Here we have a model and the model will be used to calculate shipping costs and the time required to deliver and so on.

But will you use it in the company’s web application? Most likely not. To be more precise, if you do, you really need to reread Mr. Evan’s book.

So what model will you use in such an application? I guess there will be a CQRS-like denormalized data store for you application and changes are either issued with service calls or commands. In this case you will use your models to put an even simpler SELECT * FROM SpecializedViewTable on a web page.

Something in Between

There are a few web applications that have a model that is the only bounded context and still complex enough to justify a model. If you have such a domain, you’ll be fine with the model cascade on your web application, but I have found them to be quite rare.