Paging through data in RavenDB

RavenDB has a very nice feature in it being safe by default and returns just 128 documents. Now you can override these safe defaults but it is very unwise to do so. And even if you decide to do so are you really going to show a million customers to your user at the same time? I would guess not as the user would not be really happy with the response or the speed of it. In most cases using paging is a much better solution.

 

Paging through a RavenDB result set

It turns out that paging through a result set is really easy. Normally all you need to do is use the Skip() and Take() methods and filter the result set that way. Pretty easy right?

And suppose you want to display the total number of documents or pages to the user? No need to do a separate count. The RavenDB Query() function returns an IRavenQueryable instead of a plain IQueryable object. And this IRavenQueryable gives you two extra methods one of which is Statistics() with has an out argument of type RavenQueryStatistics.

This RavenQueryStatistics is interesting because it has a TotalResults property telling us how many results are returned from the query itself. There is a second useful property for paging, SkippedResults, which is needed in some cases where RavenDB will filter out duplicate results. See here for more information on when you need to use the SkippedResults property.

 

Paging in an ASP.NET MVC page

The following controller action lets us page though a large set of people with a page size.

public ActionResult Index(int pageNr = 1)


 {


     const int pageSize = 10;


     RavenQueryStatistics stats;


 


     using (var session = Global.DocumentStore.OpenSession())


     {


         var people = session.Query<Person>()


                                  .Statistics(out stats)


                                  .OrderBy(p => p.FirstName)


                                  .Skip((pageNr - 1) * pageSize)


                                  .Take(pageSize)


                                  .ToArray();


 


         ViewBag.PageNr = pageNr;


         ViewBag.PageCount = Math.Ceiling((double)stats.TotalResults / pageSize);


 


         return View(people);


     }


 }

And this is the related Razor view

@model IEnumerable<MvcApplication1.Models.Person>


 


@{


    ViewBag.Title = "People";


}


 


<h2>People</h2>


 


<h3>Page @ViewBag.PageNr of @ViewBag.PageCount</h3>


 


<ol>


    @foreach (var item in Model)


    {


        <li>


            @Html.DisplayFor(modelItem => item.FirstName)


            @Html.DisplayFor(modelItem => item.LastName)


        </li>


    }


</ol>


 


<a href="?pageNr=@(ViewBag.PageNr + 1)">Next</a>



 







Nice and simple, just the way I like it.



 



PS. Don’t like clicking on the next button button to load more data? Neither do I. One jQuery plugin that helps me there is infinite-scroll created by Paul Irish.



 



Enjoy!

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>