Indexes in RavenDB

Whenever you search for documents in RavenDB you are using an index. Therefore indexes are a topic you must understand to effectively use RavenDB. The algorithm behind is Map/Reduce and was explained in an earlier post.

This post is part of the RavenDB series. You can find the other parts here:

 

Static vs. Dynamic

RavenDB differentiate between two types of indexes: static and dynamic. A static index is one you create yourself while a dynamic index is created when RavenDB doesn’t find a useable index for a query.

Having RavenDB creating the indexes you missed does not mean you can ignore the index creation altogether. There are some little differences between the two types you should keep in mind. Since you create the static index you also define when it is created. You can do this as part of the deployment and before a user hits the application.
The dynamic index will be created when the query can be analysed what normally means a user is waiting on an answer. If a dynamic index is not used for a certain time it will be removed. That’s not what you want for an important batch job that runs once a month…

You can however combine the two types. Fire your integration test suite against your test database and then look at the dynamic indexes RavenDB created for you. Take the ones you will often use and create them explicitly as static indexes. So you can get the best of both types and don’t need to spend a lot of time thinking about the best index definition.

 

Built in the Background

A great difference to relational databases is how RavenDB creates an index. In a relational database an insert operation needs time not only to insert the data but also to update all the indexes of the involved tables. The more indexes you have the slower an insert will be.

In RavenDB indexes are created (and updated) in the background. If you have 1 or 10 indexes does not make a difference for inserting data. The index is created asynchronously and don’t block your inserts. You get that benefit for the price of a not always 100% up-to-date index. As long as the index is updated it is marked as stale. For most use cases this is not a problem. But if you must guarantee that you use an index over all the data you can easily check if the index is stale:

 

Creating an Index

The simplest way to create an index is using the RavenDB Studio. In the Index tab you find the already existing indexes and can add a new one. All you need is a name for the index and a LINQ query for the map function:

RavenDB Index in Studio

You can query the index in the Studio using the Apache Lucene syntax. This is not so obvious but can be easily learned. A great help is the code competition you can get by using CRLT-Space as you would do in Visual Studio:

Query index in Studio

A great help is the URL in the end of the statistic block. You can use this URL directly in the HTTP API and don’t need to worry about escaping the search terms:

URI for HTTP API

You can create your indexes in C# using the IndexDefinitionBuilder class. A simple index like “AllOrdersByDestination” needs only a few lines of code:

 

Using an Index

RavenDB will use an appropriate index for your query or create a dynamic one if needed. Therefore for most cases all you need to write in your code is the query itself and you can ignore what index is used altogether.

You can force RavenDB to use a specific index. This should be well thought trough. If this index is missing RavenDB will throw an InvalidOperationException and you can no longer profit from the auto creation of dynamic indexes.

You can use a string or a type to explicitly define what index you want to use:

By using the HTTP API you are forced to specify the index when you not just want to fetch a document by its id. In the URL you need the Lucene syntax again:

 

Next

With this knowledge on indexes you should be able to try it on your own. In a future post I will explain how you can use the reduce function to answer more complicated questions. But first I want to answer an interesting question about set based operations.

 

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.