This content is retired. See latest version here.

Last updated: Sep 26 2013

Introduction

Term facets group terms, words or whole strings, and provides a count for each of them. Retrieving a term facet using the fluent API is done using the methods TermsFacetFor and TermsFacetForWordsIn.

The first of these methods works on the exact values in strings in a case sensitive manner. In other words "Foo", "foo" and "foo bar" is treated as three different terms.

The second method, TermsFacetForWordsIn, works on the analyzed values of strings meaning that it treats each word in a string a separate term. It is also case insensitive. With this method "Foo", "foo" and "foo bar" is treated as two terms, "foo" and "bar".

Both of the methods work on values of type string and IEnumerable of string. Both also have an overload that allows to specify the number of terms to return. If no size is specified the service defaults to ten.

Examples

Before we can dive in to examples we need some context to work in. Assume we have a class with a string property, a list of strings property and a property of a complex type that also has a string property:

C#
public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
    public List<string> Tags { get; set; }
}

public class Author
{
    public string Name { get; set; }
}

We also assume that we have indexed three instances of this class with the following values:

TitleTagsAuthor.Name
Ten Little Indians crime, fiction Agatha Christie
The Origin of Species science Charles Darwin
David Copperfield scifi, fiction Charles Dickens

Retriveing a tag cloud

We can now use the TermsFacetFor method to retrieve a list of the most common tags in a search request.

C#
var searchResults = client.Search<Book>()
    .TermsFacetFor(x => x.Tags)
    .Take(0)
    .GetResult();

Note that we use the Take method to exclude any actual search results as we are not interested in them in this scenario. Once we have the search result we can extract the terms facet for the tags:

C#
var tagCounts = searchResults
    .TermsFacetFor(x => x.Tags).Terms;
foreach(var tagCount in tagCounts)
{
    string tag = tagCount.Term;
    int count = tagCount.Count;
    Console.WriteLine(tag + ": " + count);
}

The above code when run would print:
fiction: 2
crime: 1
science: 1
scifi: 1

Grouping authors

If we modify the code and instead retrieve a terms facet for the author name it could look like this:

C#
var searchResults = client.Search<Book>()
    .TermsFacetFor(x => x.Author.Name)
    .Take(0)
    .GetResult();

var authorCounts = searchResults
    .TermsFacetFor(x => x.Author.Name).Terms;
foreach(var authorCount in authorCounts)
{
    string authorName = authorCount.Term;
    int count = authorCount.Count;
    Console.WriteLine(authorName + ": " + count);
}

The above code when run would print:
Agatha Christie: 1
Charles Darwin: 1
Charles Dickens: 1

Grouping by single words

In contrast, if we we're to instead use the TermsFacetForWord method instead of the TermsFacetFor method in the above code it would print:
charles: 2
agatha: 1
christie: 1
darwin: 1
dickens: 1

Comments