RavenDB – Defining indexes

time to read 3 min | 557 words

One of the more powerful features of RavenDB is the notion of indexes. Indexes allow you to query RavenDB efficiently and they stand at the core of RavenDB’s philosophy of “we shall never make you wait” and they are the express way to a lot of RavenDB’s capabilities (spatial searches and full text searches, to name just a few).

Unfortunately, indexes require that you pre-define them before you can use them. That led to a problem. A big one. It meant that in addition for simply deploying RavenDB, you had to manage additional assets, the index definitions. In essence, that is very similar to having to worry about the database schema.  That, in turn, made deploying that bit more complex, and that was unacceptable.

So we implemented the Code Only Indexes, which allow you to define your indexes as part of your project, and have them automatically created the first time the application starts.

Defining the indexes is pretty simple:

public class Movies_ByActor : AbstractIndexCreationTask<Movie>
{
    public Movies_ByActor()
    {
        Map = movies => from movie in movies
                        select new {movie.Name};
        Index(x=>x.Name, FieldIndexing.Analyzed);
    }
}

public class Users_CountByCountry : AbstractIndexCreationTask<User>
{
    public Users_CountByCountry()
    {
        Map = users => from user in users
              select new {user.Country, Count = 1};
        Reduce= results => from result in results
                           group result by result.Country into g
                           select new { Country = g.Key, Count = g.Sum(x=>x.Count)}

    }
}

But this is just the first step, the next is to tell RavenDB about them:

IndexCreation.CreateIndexes(typeof(Movies_ByActor).Assembly, store);

If you put this in your Global.asax, you would never have to think about indexing or deployment issues again.