In the previous blog* we explored indexing strategies that could be used for SOLR or Lucene. Those strategies took the configuration approach with no coding involved.

In this section of the blog we go beyond SOLR and Lucene and take a look at some strategies that can be used regardless of SOLR or Lucene and write custom code/logic. Moreover, this also enables you to add business logic behind the scenes should there be any need.

Strategy 3: Selective indexing Strategy – Code Approach

There are situations where more granularity is required. The selective indexing strategy using the configuration approach is not making the cut. You can build a custom processor to add granularity to indexes. You can do it using <indexing.filterIndex.inbound> pipeline.

In addition, you can specify a path in the content tree and exclude an item from indexing. Just implement a custom processor that checks the path of the item being processed and decides whether it should be indexed or not.

For example:

public class CustomInboundIndexFilter : InboundIndexFilterProcessor
    {
        public override void Process(InboundIndexFilterArgs args)
        {
            if (args.IndexableToIndex.AbsolutePath.StartsWith("<excluded path>"))
              args.IsExcluded = true;
        }
    }

Please note that the code above is just a sample to give you an idea of a possible customization. Please adapt it to your needs.

Strategy 4: Isolate Search Strategy – Code Approach

Add logic that will isolate a search to a particular location in the tree (roots) and templates via custom code.

Code Snippet example:

if (args.TemplateIds.Any())
                    queryable = queryable.Where(this.BuildTemplateExpression<ContentSearchResult>(args.TemplateIds));

public virtual Expression<Func<T, bool>> BuildTemplateExpression<T>(IEnumerable<ID> ids) where T : SearchResultItem
        {
            var predicate = PredicateBuilder.True<T>();

            return ids.Aggregate(predicate, (current, id) => current.Or(x => x.TemplateId == id));
        }

if (args.Roots.Any())
                    queryable = queryable.Where(this.BuildPathsExpression<ContentSearchResult>(args.Roots));

public Expression<Func<T, bool>> BuildPathsExpression<T>(IEnumerable<ID> ids) where T : SearchResultItem
        {
            var predicate = PredicateBuilder.True<T>();

            return ids.Aggregate(predicate, (current, id) => current.Or(x => x.Paths.Contains(id)));
        }

Conclusion

The above strategies should enable you to work with and customize search indexes through configuration or custom code. Alternatively, and depending on your circumstances, isolate the search path with custom code. You can pick either the configuration or add custom logic approach and then let the search provider return meaningful search results. Happy searching!

*Read part 1: Strategies for creating a meaningful site search experience with Sitecore

comments powered by Disqus