Try our conversational search powered by Generative AI!

Loading...
Area: Optimizely Search & Navigation
ARCHIVED This content is retired and no longer maintained. See the latest version here.

Recommended reading 

Search requests consist primarily of queries and filters. Queries and filters are similar, but filters provide better performance. On the other hand, filters don't affect scoring (sorting by relevance). You typically use filtering to narrow down search results (for example, limiting a free-text search for books to a specific category) or for database-like queries.

The .NET client API supports most filter types supported by the REST API, and a fluent API for common filtering operations.

A first example

Assume a BlogPost class with a Title string property. The following code finds all BlogPosts titled "Find."

C#
var searchQuery = client.Search<BlogPost>()
    .Filter(x => x.Title.Match("Find"));

The Search<TSource> method returns an instance of ITypeSearch<TSource>, which acts as a builder class for a search request. Using the Filter extension method, you can add a filter to the search request by supplying an expression that returns an instance of the Filter class. The client API has several extension methods for value types and strings that return filters, such as the Match method above.

Grouping filters

You can group filters using Boolean operators. For example, the following code finds blog posts titled "Find" or "Search."

C#
var searchQuery = client.Search<BlogPost>()
    .searchQuery.Filter(
        x => x.Title.Match("Find") 
           | x.Title.Match("Search"));

Assuming the BlogPost class has a Tag property, the following code finds blog posts titled "Search" and tagged with "Find," or titled "Find" (with no requirements for tags).

C#
var searchQuery = client.Search<BlogPost>()
    .Filter(
        x => (x.Title.Match("Search") & x.Tags.Match("Find")) 
            | x.Title.Match("Find"));

Calling Filter multiple times

You can call the Filter method multiple times, which is useful if filters you want to apply are determined at runtime, such as filters that depend on user input. For example, you can modify the first part of the filter expression above as follows:
C#
var searchQuery = client.Search<BlogPost>()
    .Filter(x => x.Title.Match("Search"))
    .Filter(x => x.Tags.Match("Find"));

The OrFilter method

If you invoke the Filter method multiple times, the latter invocations' filters are combined with previous invocations' filters using AND. To combine them using OR, use the following code.
C#
var searchQuery = client.Search<BlogPost>()
    .Filter(x => x.Title.Match("Search"))
    .Filter(x => x.Tags.Match("Find"))
    .OrFilter(x.Title.Match("Find"));

If the OrFilter method is called before the Filter method, it is the same as calling the Filter method, since there is no existing filter with which to OR-group it.

Complex and dynamically created filters

Sometimes, the Filter and OrFilter methods are not enough. For example, you build complex search queries dynamically at runtime based on user input. While the methods can handle most scenarios at compile time, creating multiple grouped Or-filters at runtime is tricky and results in complex code. To build filters without regard to other filters and apply them to a search query, using the IClient extension method BuildFilter.

The BuildFilter method requires a generic type parameter to which you apply the filter. The method returns an object of type FilterBuilder. The FilterBuilder class has And and Or methods, which you use to can add filter expressions like the Filter and OrFilter methods. The FilterBuilder class is implicitly convertible to the Filter class, so you can pass instances of it as arguments to the Filter and OrFilter methods and in filter expressions.

For example, you manage a restaurant search that uses two variables: cuisines and countries, both of type IEnumerable<string>. Both may be null, but if either is not, you want to add a filter so that search results return only restaurants matching those cuisines or countries. Use the BuildFilter method to accomplish this.

C#
var q = ... some search string

ITypeSearch<Restaurant> query = 
    client.Search<Restaurant>().For(q);

if (cuisines != null)
{
    var cuisineFilter = client.BuildFilter<Restaurant>();
    foreach (var cuisine in cuisines)
    {
        cuisineFilter = cuisineFilter.Or(
            x => x.Cuisine.Match(cuisine));
    }
    query = query.Filter(cuisineFilter);
}

if (countries != null)
{
    var countryFilter = client.BuildFilter<Restaurant>();
    foreach (var country in countries)
    {
        countryFilter = countryFilter.Or(
            x => x.Country.Match(country));
    }
    query = query.Filter(countryFilter);
}

var results = query.GetResult();

Filtering methods

When filtering with the Filter method, you provide an expression that returns a filter. To do so, use extension methods for properties that return filters. The above examples used the Match extension method, but several other methods exist. It is also possible to create custom extension methods to enhance the filtering functionality.

  • Filter methods for strings
  • Filter methods for numerical fields (int, int?, double etc)
  • Filter methods for DateTime fields
  • Filter methods for boolean fields
  • Filter methods for enum fields
  • Filter methods for GeoLocation fields
  • Filter methods for complex objects
Do you find this information helpful? Please log in to provide feedback.

Last updated: Apr 20, 2015

Recommended reading