HomeDev GuideRecipesAPI ReferenceGraphQL
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunityDoc feedbackLog In
GitHubNuGetDev CommunityDoc feedback

Range facets

Describes how facets based on range are used in Optimizely Search & Navigation.

Facets are used for grouping documents based on some criteria, for example specific terms or a date range. 

Range facets group documents based on ranges into which a numeric or DateTime field falls. Unlike Histogram facets, the ranges need not be an interval, such as 0-10, 10-20. Instead, they can be different sizes and overlap each other, such as 0-10, 5-20. Also unlike histogram facets, range facets return more than just the number of documents in each range, such as minimum, maximum, and mean values.

To request range facets, use the RangeFacetFor method. Its first parameter is an expression, which you use to select the property by which to group documents. The second parameter is an array (params) of either NumericRange or DateRange objects, depending on the first parameter's property type. Both numeric or DateTime field range types have two properties, named From and To, of type nullable double and nullable DateTime, respectively.

After executing a search request with range facets, you retrieve facets from the result object using the RangeFacetFor method (the same name used to request them). This method has one parameter, an expression saying what property the range facet is for.



Ranges are inclusive for the lower bound and exclusive for the upper bound. That is, a range from 0 to 10 matches 0 but not 10. The same goes for date ranges, where a range from 2012-01-01 to 2012-01-31 matches 2012-01-01 but not 2012-01-31.

The following example groups products into three price ranges.

var priceRanges = new List<NumericRange>()
    new NumericRange { To = 100 },
    new NumericRange { From = 100, To = 300 },
    new NumericRange { From = 300 }

var searchResult = client.Search<Product>()
  .RangeFacetFor(x => x.Price, priceRanges.ToArray())

In the above example, you create a number of ranges and request a range facet for products falling into those ranges. In the first range, you do not specify the From property, effectively saying that the range is for products with a price below 100. Similarly, the third range does not specify the To property, requesting all products that cost 300 or more.

Upon retrieving the search result, you can retrieve and inspect the facet. Below is an example of doing this, writing information about each range to the console.

var priceFacet = searchResult.RangeFacetFor(x => x.Price);

foreach (NumericRangeResult range in priceFacet)
    if (range.From.HasValue)
        Console.Write(" from " + range.From.Value);
    if (range.To.HasValue)
        Console.Write(" to " + range.To.Value);
    Console.WriteLine("Count: " + range.Count);
    Console.WriteLine("Min: " + range.Min);
    Console.WriteLine("Max: " + range.Max);
    Console.WriteLine("Mean: " + range.Mean);
    Console.WriteLine("Total: " + range.Total);

The above code produces output like this:

Range to 100
Count: 61
Min: 0,5
Max: 97,3
Mean: 42,3237045467812
Total: 2581,74597735365

Range from 100 to 300
Count: 52
Min: 100,0
Max: 299,0
Mean: 205,738167025743
Total: 10698,3846853387

Range from 300
Count: 51
Min: 301,5
Max: 942,8
Mean: 566,562194859469
Total: 28894,6719378329