Ayende @ Rahien

It's a girl

NuGet Perf, Part VII AKA getting results is only half the work

So far, we have been focusing on various ways to get the raw results from RavenDB. What are the packages that match your queries, and whatever we can be really smart about it.

But let us say that we got the results that we wanted, this is still just half the work, because we can give the user additional information about those results. In particular, in this post I am going to talk about facets.

Facets are a way to provide easily understood context to a search, allowing the user to narrow down what he is looking for quickly. In our case, let us take a look what it takes to add facet supports to our NuGet console app. The first thing to do, of course, is to actually define the facets we want to work on. In this case, we care only for the Tags:

using (var session = store.OpenSession())
{
    session.Store(new FacetSetup
        {
            Id = "facets/PackagesTags",
            Facets =
            {
                new Facet
                    {
                        Name = "Tags",
                        MaxResults = 4,
                        Mode = FacetMode.Default,
                        TermSortMode = FacetTermSortMode.HitsDesc
                    }
            },
        });
    session.SaveChanges();
}

When doing facet search using this document, we will use the Tags field, using a value per each term found. We want to get the top 4, sorted by their hits.

And here is how we are actually doing the faceted query:

var facetResults = q.ToFacets("facets/PackagesTags");
foreach (var result in facetResults.Results)
{
    Console.WriteLine();
    Console.Write("{0}:\t", result.Key);
    foreach (var val in result.Value.Values)
    {
        Console.Write("{0} [{1:#,#}] | ", val.Range, val.Hits);
    }
    Console.WriteLine();
}

It is a one liner, with all of the rest of the code dedicated to just printing things out.

Finally, here are the results:

image

As you can see, searching for “dal”, we can narrow the searches for linq, orm, etc. Searching for events, we get reactive extensions, etc.

Using facets gives the user additional information about his search (including things like, am I close to what I want), discoverability over your dataset and additional tools to explore it.

All in all, I think that this is a pretty neat thing.

Comments

Phillip Haydon
09/05/2012 09:25 AM by
Phillip Haydon

Are you planning to put this on github (if it isn't already?) would be awesome to learn from, touches a few really interesting things.

Ayende Rahien
09/05/2012 10:02 AM by
Ayende Rahien

Philip, It is already on Github (ayende/nuget.perf)

Stuart King
09/05/2012 11:53 AM by
Stuart King

This is a great series of posts, learning so much about RavenDB. Opening my mind to so many possibilities. Thanks!

Fujiy
09/05/2012 04:01 PM by
Fujiy

Reading http://ravendb.net/docs/client-api/faceted-search I did´t get how RavenDB knows what field to use. It split the Facet name by ""? Ex.: Will Name = "CostRange" read the Cost field?

Ayende Rahien
09/06/2012 06:51 AM by
Ayende Rahien

Cost_Range is the numeric value field that is generated by RavenDB.

tucaz
09/17/2012 04:31 PM by
tucaz

Looks like the facets are an "entity" that is generated for each query and not an actual column/index in the raw data. Now that you listed all facets for a given query, how would you filter EXACTLY by that facet to get only the results that match a certain facet?

Comments have been closed on this topic.