The RAW stack and filtering movies by genre

One of the options on the movie list was a set of buttons with each movies genres. This list is nice to see what a movie is about but also rather useful to filter movies on. It turns out filtering documents on one or more tags in a collection of tags is rather easy to do using RavenDB.

 

Using RavenDB’s LuceneQuery

RavenDB uses Lucene for it’s indexing capabilities making it very capable for querying. Originally we where using the standard RavenDB query capability but now we will switch to using the LuceneQuery(). Form the AngularJS client we can pass the, optional, list of genres we are interested in and if passed add a simple Lucene query to the RavenDB query, all pretty simple. The only thing is that for an array of strings on the query string we need to specify the WebAPI that it should actually check the URI as well.

 

   1: public IEnumerable<Movie> GetMovies(int page, [FromUri]string[] genres)

   2: {

   3:     const int pageSize = 128;

   4:  

   5:     var query = _session.Advanced.LuceneQuery<Movie>();

   6:     if (genres.Length > 0 && genres[0] != null)

   7:     {

   8:         var filter = "Genres:(\"" + string.Join("\" AND \"", genres) + "\")";

   9:         query = query.Where(filter);

  10:     }

  11:  

  12:     var movies = query

  13:         .OrderBy(m=> m.Title)

  14:         .Skip(page * pageSize)

  15:         .Take(pageSize)

  16:         .ToList();

  17:  

  18:     return movies;

  19: }

 

Updating the AngularJS client

The server part was simple enough so now we need to update the client parts of the application.

First of all it is best to introduce AngularJS routing. That way the user can use the back button and have the normal and expected behavior from the browser. So we need to include angular-route.min.js and take a dependency on ngRoute. Next we need to configure our routes, in this case I have added two. The first is the route with no genres selected and the second for when the user has one or more genres selected. Both use the same controller as there really is little difference between the two.

Next we need to move the markup to a separate template and include the ngView directive as the placeholder for the template and controller. All pretty straightforward AngularJS material.

 

Try it

The running application can be found here and the source on GitHub here.

Conclusion

The fact that RavenDB includes Lucene for its indexes makes it really easy to do powerful queries. The routing and flexibility of AngularJS make it really easy to create a flexible client application. Sweet 🙂

 

Index of posts on the RAW stack

See here for more posts on the RAW stack.

Leave a Reply

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