Porting MVC Music Store to RavenPorting the HomeController, the map/reduce way

time to read 4 min | 621 words

The current HomeController looks like this:

image

I really don’t like the fact that the controller issues queries like that, but we will let it go for now.

This query (thanks to EF Prof) looks like this:

image

And here we run into a very interesting problem, we can’t really replicate this query. The reason is that this query runs over multiple tables which our model says would be in different documents.

There are several ways in which we can fix this. One way of doing this would be to define a map / reduce index on top of orders.

Note: Yes, I am familiar with this comic.

The way that I am about to show you isn’t the way I would recommend going for real, but I want to show it anyway. I’ll discuss the idiomatic Raven way of handling this feature in my next post.

Map/reduce in Raven is just a couple of Linq queries, so it is nothing to be worried about. As a reminder, we have the following order documents in our database:

image_thumb9 image image

We define the index “SoldAlbums” using the following queries.

// map
from order in docs.Orders
from line in order.Lines
select new{ line.Album, line.Quantity }

// reduce
from result in results
group result by result.Album into g
select new{ Album = g.Key, Quantity = g.Sum(x=>x.Quantity) }

As you can see, those are two very simple Linq queries.

The result of which would be:

image

Once we have that, it is trivial to derive the answer to GetTopSellingAlbums. Indeed, the following function implements the exact same logic and has the same output as the previous implementation:

image

The way it work is pretty simple, we get the most sold albums (by sorting on descending quantity), then load them from the database. Because we might have less than count top selling albums, we need to top it off from regular albums.

This mean that this code execute 2 – 3 queries. I don’t really like it, but on my machine, it takes about less than 10 ms to do all three requests, which is livable.

The reason that I am posting this solution is that I want to show this as an approach to a problem, not as the recommended approach for how to solve it, I’ll do that in my next post.

More posts in "Porting MVC Music Store to Raven" series:

  1. (31 May 2010) StoreManagerController, part 2
  2. (29 May 2010) StoreManagerController
  3. (28 May 2010) Porting the checkout process
  4. (25 May 2010) StoreController
  5. (24 May 2010) Advanced Migrations
  6. (23 May 2010) Migrations
  7. (22 May 2010) Porting the HomeController, the Right Way
  8. (21 May 2010) Porting the HomeController, the map/reduce way
  9. (20 May 2010) Data migration
  10. (19 May 2010) Setting up the application
  11. (18 May 2010) The data model