Ayende @ Rahien

It's a girl

RavenDB – Defining indexes

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.

Tags:

Posted By: Ayende Rahien

Published at

Originally posted at

Comments

GeeBee
10/21/2010 08:31 AM by
GeeBee

[disclaimer]I've not looked at ravendb so maybe this is already available or not a good idea.[/disclaimer]

Something that springs to mind reading this is that as index definitions implement AbstractIndexCreationTask <t maybe there could be a method IndexCreation.AutomaticDiscovery()? This could then scan your assembly for any types implementing AbstractIndexCreationTask and include them?

Ayende Rahien
10/21/2010 08:35 AM by
Ayende Rahien

GeeBee.

Which assemblies should it scan?

Dennis
10/21/2010 08:52 AM by
Dennis

What about upgrade scenarios for this? If i alter an index or remove one?

Ayende Rahien
10/21/2010 08:55 AM by
Ayende Rahien

Dennis,

If you remove an index, you need to explicitly remove it.

If you alter it, it will update

wouzer
10/21/2010 09:36 AM by
wouzer

This code doesnt compile. ;-)

Ayende Rahien
10/21/2010 10:34 AM by
Ayende Rahien

Wouzer,

This is happening on the unstable fork.

Erik
10/21/2010 01:33 PM by
Erik

What sort of syntax is this?

Ayende Rahien
10/21/2010 01:37 PM by
Ayende Rahien

Erik,

You need to explain a bit more on that

Erik
10/21/2010 01:47 PM by
Erik

I'm referring to this:

public Movies_ByActor()

{

....

}

-- What is that construct? It doesn't seem to be valid C# code. What is the type of 'Movies_ByActor'? It can't be a method because there's no return type; it can't be an anonymous object because it's not local to any methods; it can't be a property because it doesn't have getters or setters; it can't be a class or struct itself because... well, there's no class or struct keywords.

Basically the syntax is confusing me - it's also confusing Visual Studio. Perhaps I'm showing my ignorance. =P

Erik
10/21/2010 01:49 PM by
Erik

Okay - I'm a little less confused now - I forgot about constructor syntax. Lol

But the second example - 'public Users()' - that still stands; was that a typo, and should have been 'public Users_CountByCountry' ?

Ayende Rahien
10/21/2010 02:11 PM by
Ayende Rahien

Erik,

Yes, the second one was a typo, fixed

Erik
10/21/2010 02:14 PM by
Erik

Okay, cool, thanks - I'm not going insane. =)

configurator
10/21/2010 02:36 PM by
configurator

How about IndexCreation.AutomaticDiscovery(Assembly ass); ?

Ayende Rahien
10/21/2010 03:47 PM by
Ayende Rahien

Configurator,

That is what this does, doesn't it?

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

configurator
10/21/2010 03:50 PM by
configurator

I missed the .Assembly there! I thought it was just for that specific type...

JimY
10/21/2010 09:58 PM by
JimY

Ayende i m confident u have the ressources to bring this from an experiment to a major product.

Any chance RavenDB will get more coverage and grow as first class storage ?

wouzer
10/22/2010 03:15 PM by
wouzer

cool, you found why it didnt compile.

btw. love your work on these projects man.

I've been looking for this...
10/27/2010 05:45 PM by
I've been looking for this...

Thanks for doing this, I've been rolling my own index creator. I can't seem to find it in the assembly though. I'm using Raven.Client-3.5. Is this only available on the lightweight assembly?

Ayende Rahien
10/27/2010 06:40 PM by
Ayende Rahien

Miguel,

Yes, it is available in 4.0 only (relies on the MEF stuff)

Comments have been closed on this topic.