Example: Pluggable EPiServer Find UnifiedSearch for selected types

In this example on how the pluggable EPiServer Find UnifiedSearch may be implemented we will look at simple type filtering. Previously we did this using TypeSearch, but since we moved to UnifiedSearch in my current project, it had to be reimplemented. For more information, please see the previous article A way of consolidating EPiServer Find Unified Search over multiple websites. You may also be interested in Ajax support for the pluggable EPiServer Find UnifiedSearch implementation.

The first thing you need to do is inherit the SpecificSearchBase class. Since we need the types we want to filter on, we can supply these when creating the object.

In this class we can override methods in order to inject what we need. For instance, we can add meta information to the result in the AddResultMetaSpecifics method.

internal class LimitedSearchSpecifics : SpecificSearchBase
{
  private readonly IEnumerable<Type> _types;

  public LimitedSearchSpecifics(IEnumerable<Type> types)
  {
    _types = types ?? throw new ArgumentNullException(nameof(types));
  }
        
  public override SearchResult AddResultMetaSpecifics(SearchResult returnResult, UnifiedSearchResults findResult, SearchParameters parameters)
  {
    returnResult.ShowTotalText = "Some text based on parameters and result, or some other code.";
    return returnResult;
  }

  public override IQueriedSearch<ISearchContent, QueryStringQuery> AddQuerySpecifics(IQueriedSearch<ISearchContent, QueryStringQuery> search, SearchParameters parameters)
  {
    return search.FilterByExactTypes(_types);
  }

  public override HitSpecification HitSpecification()
  {
    return new HitSpecification { HighlightExcerpt = false };
  }
}

The types that we want to filter on should affect the EPiServer Find query, so override the AddQuerySpecifics, and apply the additional type filtering.

We can also for instance choose not to have hit text highlighting by doing the same in HitSpecification. In the base class you can see what else you can override.

Then just perform the search using your new specifics object and the current request.

HttpRequest request = HttpContext.Current?.Request;
string query = request?.QueryString?["q"];
if (string.IsNullOrWhiteSpace(query))
{
  return null;
}
HttpRequestBase requestBase = new HttpRequestWrapper(request);

Type[] types = new[] {
  typeof(ArticlePage),
  typeof(CustomIndexedObject),
};
SpecificSearchBase specifics = new LimitedSearchSpecifics(types);

return _searchService.SearchFor(requestBase, specifics);