In the previous post RavenDB Tutorial, Part 1 - Introduction and Basic Operations I’ve described fundamental topics requiring your attention before you start coding and also presented how to initialize database, persist documents, load and delete them. I wanted to make indexing and querying a separate posts because, my observation is, these topics are a little bit more advanced and tricky to work with. There are some caveats you need to be aware of and careful about and at least in theory so many different articles describing the topic, but in my opinion none of them are any good and very often they do more harm (by confusing the hell out of you) than actually explain. So this is the post I wish I had a chance to read before approaching the topic for the first time.
First of all - we need to have some data we will be able to query upon. From my experience there are two favorite types of data folks out there are modeling for the purposes of blog posts and tutorials about document databases - orders and blog posts. Some time ago I thought it’s cliché and not really original, but now I believe this is for a reason. And the reason is that those are entities one can be almost sure readers of a blogs committed to coding/development have seen, used and experienced. What is more - those are so common in so-called ‘real life’ we don’t need to think too much to ‘see’ a mental model in our heads, which in turn means we’re not using precious brain-processor circles on digesting the being of an entity - but instead we can focus on the new material at hand. But I don’t like following standard path, so in my tutorial I will be querying against database containing people. Not real people of course, but object representation of entities of class ‘Person’ having a few very simple properties, which as orders and posts are rally easy to comprehend. To avoid distraction - I’ve prepared a solution which contains a few projects with code accompanying posts for this series.
It can be found on GitHub, here: Geekbeing.Blog.RavenDb.Tutorial. With that you can create a copy of RavenDB and data (‘readme’ file in GitHub repository describes how to set it up) for yourself pretty easily and take a look at the code I’ll be discussing in this post. ‘Readme’ also instructs you on how to setup your database and populate it with the entities. Console application shows some basic querying, while ASP .NET MVC 3 based sample shows more advanced scenario (not that advanced, though, we will take on more complex querying in the upcoming posts). Let’s go!
First thing you might want to do, would be to find out how many records (entities, or better - documents in RavenDB’s nomenclature) there are. For code I’m about to present make more sense to you familiarize yourself with at least two interfaces in .NET - IQueryable
1 2 3 4 5 6 | |
Looking at the code we need to be aware that first two lines in using statement are not triggering a call to Raven. Only in third line, because we call ‘ToList()’ method - actual request to database is made.
One of the caveats one needs to be aware of when working with Raven is presented in the code below. For the sake of the example you must know I’ve seeded my instance of the database with 220 documents, each of these representing object of ‘Person’ class (part of the aforementioned solution, available for download). What do you think happens when you call code below?
1 2 3 4 | |
Interesting thing is that if you count how many object variable ‘people’ holds - you will encounter not the exact amount of the docs of given type in RavenDB server instance you are querying - but 128 elements (no more than 128, no matter how many there actually are). It’s a feature, not a bug. This is by design as it is hard to think about a situation where you’d actually need more records than that all at once (Although I can easily think of a situation where some people would think they need it). So this constraint is here to prevent you from shooting yourself in the foot. There is plenty of information online where Ayende explains his motives behind this choice. Also this limit can be changed in the server configuration - but do it at your own risk - it is strongly recommended against doing so. The question you might think of right now is - How do I know how many documents of a given type are actually there? This might be interesting because you could e.g. be interested in presenting your users with a number of the accounts that have been already registered for your service. Or implement pagination, which is very common scenario nowadays. Part of the information you are going to need is a total count of the documents you will be presenting to the user of the application. It could be done this way (don’t copy paste this code, it’s just to present some concepts, but it’s flawed)
1 2 3 4 5 6 7 8 9 10 11 12 | |
Let me explain myself… I start by opening the session and then issue
Query
A pretty obvious scenario is presented at RavenDB paging - unfortunately example does not show how the rest of the code (pagination logic, views) is implemented. I think RavenDB itself is much more awesome than documentation for it. It has improved a lot recently, but to me and friends I’ve discussed this issue with - it’s lacking information in many places, or showing only the happiest/simplest path, always leaving us with obvious questions we’d like to ask further, but unfortunately - no answers. Should you feel the same about the material I’m presenting in this post - drop me an e-mail, I’ll be glad to sort things out for you (and for myself by the way).
As I’ve mentioned - Geekbeing.Blog.RavenDb.Tutorial contains project Geekbeing.Blog.RavenDb.Tutorial.Web, which is a simple ASP .NET MVC 3 based web application presenting how to paginate through the list of documents of type ‘Person’. It’s not important from Raven’s perspective, but default MVC UI (User Interface) template is replaced with something more contemporary. I’m mentioning it only because this will be partially a topic for soon to be published post on this blog - summary of the modern web-dev tools I’m using. For now - you can take a look at this really small MVC app and take a look at how pagination is implemented.
Ok, enough about pagination. When querying you might also use .Where() extension method and limit the result set that will be returned by Raven. Let’s say out of all of the documents of type ‘Person’ you would like to retrieve all of the people that have a first name ‘Laura’. Here’s how:
1 2 3 4 5 6 | |
Please keep in mind the code above might or might not yield results when you run it on your computer. When you’ll be seeding the data using one of the projects in my solution on GitHub - all of the ‘Person’ class instances have random values assigned to each of their properties. You might end up with 200+ Lauras or with none at all. One more thing worth mentioning is that you can also use LINQ syntax when querying RavenDB.
1 2 3 4 5 6 7 8 9 10 | |
This sums up basic Querying, in the next few posts about RavenDB I’ll talk a little bit about small tips and tricks when setting up your local dev environment, how you can profile your application, view logs, monitor traffic and in another post I’ll be getting to more advanced querying and in following post - indexes. See you soon!