Fun with RavenDB 2

This is the second post in a small series about RavenDB – a document database in .NET. I will try to touch the same areas as I did in my series on MongoDB, possibly comparing the two where I see fit.

Now, this time we will take a look at querying…

Introduction

Querying with MongoDB is extremely easy and intuitive when you’re used to relational databases – just type in some queries in the form of JSON documents and send them to the server and let it do its work.

Querying with RavenDB is a different story, because the only thing that can be queried is an index[1. Or is it? I should point out that Ayende said that RavenDB would have dynamically generated temporary indexes in the future, allowing ad-hoc quering… but what’s more, those temporary indexes would “materialize” and become permanent if you hit them enough times… that actually sounds extremely cool, and should allow for some truly frictionless and agile-feeling development.]. Let’s see…

Simple query

Let’s start out by handing a couple of documents to the server. Let’s execute the following:

Now, in order to be able to query these documents, we need to tell RavenDB to create an index… I like to be code-driven when I can, so let’s do it with C#… first, make a class somewhere derived from AbstractIndexCreationTask:

In this example, I build the index purely from mapping the collection – i.e. there’s no reduce step. Note that the map step is a LINQ query that maps each document into the fields that should be used to build the index. That means that the example above will allow me to query this index and constrain by ViewCount of each movie.

Next, upon initialization, we need to tell RavenDB to create our indexes (if they have not already been created – otherwise, they’ll be updated):

That was easy. Now, let’s take the index for a spin… first let’s just get everything [1. Note that because of RavenDB’s excellent safe-by-default philosophy, at most 128 documents will be returned! Therefore, the usual .Skip(n) and .Take(m) methods should be used to properly page the result sets.

Note also, that by default you can perform only 30 operations resulting in remote calls within one IDocumentSession. This is another constraint that will guide you away from blowing off that left foot of yours :)]:

which results in the following output in the console:

which is pretty much what we expected. Note however that RavenDB is nice enough to tell when a query is executed and how many results are returned.

Now let’s use our index and change the query into this:

which gives me the following output:

Note how the query criteria are translated into a Lucene query – that’s because RavenDB uses Lucene. NET for all of its indexing work. Just for the fun of it, let’s try using the index to constrain by title:

which results in the following output:

It appears RavenDB will just go ahead and query Lucene for it, even though the index doesn’t have the specified field. Kind of weird, but maybe it’s because Lucene is itself a document DB, and there’s no way to tell beforehand whether a given index contains a document with the specified field.

Now that was a couple of simple queries. Next time, let’s try building a map/reduce query!

2 thoughts on “Fun with RavenDB 2

  1. “Now, in order to be able to query these documents, we need to tell RavenDB to create an index… ”

    That’s not actually true either, it is recommended that you use the relatively new feature to just use

    session.Query().Where(x=>x.SomeProperty == "Something" // etc).ToArray()

    Which will create the index for you in the background 🙂

  2. Yeah, that feature is pretty cool! I mention that in the first footnote whose reference, I admit, is way too hard to see 🙂 I will correct that.

    Wait – so you’re saying that LINQ querying is the recommended way of creating the index?

    I can see why this is a nice feature for simple queries, but won’t you get in trouble with some more advanced queries?

Leave a Reply

Your email address will not be published. Required fields are marked *

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