0

I'm using C# to query Solr for my site search. The code is fine in regard to filtering and searching for keywords in specific fields, but I can't get Boost to work. I need to use boosting so that items where the keyword is in the Title field are returned first, then keyword in the Description field, then keyword in the Content.

My search code creates a SearchQuery and adds a QueryBuilder containing a PredicateBuilder to SearchQuery.QueryBuilders. This is a simplified version of my code (took out non-relevant code)

public SearchQueryResults Search(string keywords){
     SearchQuery<KofaxSearchResultItem> queryArguments = new SearchQuery<KofaxSearchResultItem>();
     List<IPredicateBuilder<KofaxSearchResultItem>> queryBuilders = new List<IPredicateBuilder<KofaxSearchResultItem>>();
     var keywordPredicate = new ExactKeywordPredicateBuilder(keywords, _sitecoreContext);
     queryArguments.QueryBuilders = queryBuilders;
     var results = _searchManager.GetResults<KofaxSearchResultItem>(queryArguments);
     (return results after some more stuff)
}

class ExactKeywordPredicateBuilder : IPredicateBuilder<KofaxSearchResultItem>
{
    public string Query { get; set; }
    public List<Guid> ContentTypeFilters { get; set; }
    SearchTaxonomyUtil SearchTaxonomyUtil { get; set; }

    public ExactKeywordPredicateBuilder(string query, ISitecoreContext sitecoreContext, List<Guid> contentTypeFilters = null)
    {
        Query = query;
        ContentTypeFilters = contentTypeFilters;
        SearchTaxonomyUtil = new SearchTaxonomyUtil(sitecoreContext);
    }

    public Expression<Func<KofaxSearchResultItem, bool>> Build()
    {
        return SearchTaxonomyUtil.GetKeywordPredicate(Query, ContentTypeFilters);
    }
}

public Expression<Func<SearchResultItem, bool>> GetKeywordPredicate(string keyword)
{
    keyword = keyword.ToLower();
    var predicate = PredicateBuilder.True<SearchResultItem>();

    predicate = predicate.Or(r => r.Title.Contains(keyword)).Boost(1000f);
    predicate = predicate.Or(r => r.ShortPageSummary.Contains(keyword)).Boost(10f);
    predicate = predicate.Or(r => r.Content.Contains(keyword)).Boost(0.1f);

    return predicate;
}

I get the correct results in that I only get items that contain the keyword, but the boosting isn't doing anything. I'm getting keyword-in-Description results ahead of keyword-in-Title results, and if I change the boosting to make ShortPageSummary boosted higher than Title, or remove the .Boost()s altogether, the results remain the same.

I am not passing in any SortBuilder, so the sorting is whatever Solr does by default. I tried setting this:

queryArguments.SortBuilder = new GenericSortBuilder<SearchResultItem>(q => q.OrderBy(r => r["score"]));

but that returned completely jumbled results that seemed to be in worse order than they were before.

EDIT: I checked the Solr logs and the Boost is not being added to the query that is being passed to Solr.

Erica Stockwell-Alpert
  • 4,624
  • 10
  • 63
  • 130
  • Have you tried checking the Solr log to see what the actual query being sent to Solr is? (i.e. if the boost is actually added to the query, so that you know if the issue is in how the query is built or how Solr is scoring the documents) – MatsLindh Jun 08 '18 at 09:38
  • The boost appears to NOT be getting added to the query, my Solr logs show the query but with no boost. – Erica Stockwell-Alpert Jun 08 '18 at 14:21
  • I think you have to use PredicateBuilder for each of your conditions and apply the boost to that predicate, then use `.Or(predicate1).Or(predicate2)`, etc. – MatsLindh Jun 08 '18 at 15:03
  • See [example here](https://stackoverflow.com/questions/38261886/sitecore-search-predicate-builder-multiple-keyword-search-with-boosting-not-work) – MatsLindh Jun 08 '18 at 15:36

0 Answers0