0

I'm using Solr 7.5 with Sitecore 9.2. I have some complex code that generates a search query, which I'm now trying to apply boosting to to prioritize page items over media assets (the relevant lines begin at isAssetPredicate....

    public override Expression<Func<T, bool>> Build()
    {
        string query = _values.FirstOrDefault();
        string queryLower = query.ToLower();

        if (string.IsNullOrEmpty(query)) return null;

        var predicate = PredicateBuilder.False<T>();

        var exactPredicate = PredicateBuilder.False<T>();
        exactPredicate = exactPredicate.Or(x => x.ItemPartNumberLower.Contains(queryLower)).Boost(90);
        exactPredicate = exactPredicate.Or(x => x.TitleLower.Contains(queryLower)).Boost(99);
        exactPredicate = exactPredicate.Or(x => x.Keywords.Contains(queryLower)).Boost(9);
        exactPredicate = exactPredicate.Or(x => x.FileType.Contains(queryLower)).Boost(9);
        exactPredicate = exactPredicate.Or(x => x.AggregatedSearchFields.Contains(queryLower)).Boost(9);

        var fuzzyPredicate = PredicateBuilder.False<T>();
        fuzzyPredicate = fuzzyPredicate.Or(x => x.ItemPartNumberLower.Contains(queryLower)).Boost(90);
        fuzzyPredicate = fuzzyPredicate.Or(x => x.TitleLower.Contains(queryLower)).Boost(99);
        fuzzyPredicate = fuzzyPredicate.Or(x => x.Keywords.Contains(queryLower)).Boost(9);
        fuzzyPredicate = fuzzyPredicate.Or(x => x.FileType.Contains(queryLower)).Boost(9);
        fuzzyPredicate = fuzzyPredicate.Or(x => x.AggregatedSearchFields.Contains(queryLower)).Boost(9);

        // try searching for each term separately rather than exact match
        var queryParts = queryLower.Trim().Split(' ');
        if (queryParts.Length > 1)
        {
            var partsPredicate = PredicateBuilder.True<T>();
            var fuzzyPartsPredicate = PredicateBuilder.False<T>();
            foreach (var part in queryParts)
            {
                if (String.IsNullOrEmpty(part)) continue;

                var subQuery = PredicateBuilder.False<T>();
                subQuery = subQuery.Or(x => x.TitleLower.Contains(part)).Boost(99);
                subQuery = subQuery.Or(x => x.ItemPartNumberLower.Contains(part)).Boost(95);
                subQuery = subQuery.Or(x => x.Keywords.Contains(part)).Boost(80);
                subQuery = subQuery.Or(x => x.FileType.Contains(part)).Boost(1);
                subQuery = subQuery.Or(x => x.AggregatedSearchFields.Contains(part)).Boost(1);

                partsPredicate = partsPredicate.And(subQuery);

                var subQueryFuzzy = PredicateBuilder.False<T>();
                subQueryFuzzy = subQueryFuzzy.Or(x => x.TitleLower.Like(part)).Boost(99);
                subQueryFuzzy = subQueryFuzzy.Or(x => x.ItemPartNumberLower.Like(part)).Boost(95);
                subQueryFuzzy = subQueryFuzzy.Or(x => x.Keywords.Like(part)).Boost(80);
                subQueryFuzzy = subQueryFuzzy.Or(x => x.FileType.Like(part)).Boost(1);
                subQueryFuzzy = subQueryFuzzy.Or(x => x.AggregatedSearchFields.Like(part)).Boost(1);

                fuzzyPartsPredicate = fuzzyPartsPredicate.Or(subQueryFuzzy);
            }
            exactPredicate = exactPredicate.Or(partsPredicate).Boost(1);
            fuzzyPredicate = fuzzyPredicate.Or(fuzzyPartsPredicate).Boost(1);
        }

        var queryPredicate = PredicateBuilder.False<T>();
        queryPredicate = queryPredicate.Or(exactPredicate).Boost(99);
        queryPredicate = queryPredicate.Or(fuzzyPredicate).Boost(1);

        predicate = predicate.Or(queryPredicate);

        if (HasAttribute(FieldType.Title))
        {
            predicate = predicate.Or(GetQueryExpression(FieldType.Title, query));
        }
        if (HasAttribute(FieldType.Description))
        {
            predicate = predicate.Or(GetQueryExpression(FieldType.Description, query));
        }

        if (HasAttribute(FieldType.Body))
        {
            predicate = predicate.Or(GetQueryExpression(FieldType.Body, query));
        }
        else if (QueryFormatter.NeedsFormatting(query))
        {
            predicate = predicate.Or(x => x.Content.MatchWildcard(QueryFormatter.FormatQuery(query)));
        }
        else
        {
            predicate = predicate.Or(x => x.Content.Like(query, SiteSettings.MinimumSimilarity));
        }

        var isAssetPredicate = PredicateBuilder.True<T>().And(x => x.IsAsset.Boost(0.0000001f)).And(predicate).Boost(0.0000001f);
        var isPagePredicate = PredicateBuilder.True<T>().And(x => !x.IsAsset.Boost(9999f)).And(predicate).Boost(9f);

        var finalPredicate = PredicateBuilder.True<T>();
        finalPredicate = finalPredicate.Or(isAssetPredicate.Boost(0.1f)).Boost(0.1f);
        finalPredicate = finalPredicate.Or(isPagePredicate.Boost(9f)).Boost(9f);

        return finalPredicate;
    }     

As you can see I've put boosting in multiple places (I've tried it both within the predicate and outside the predicate separately as well as together) but none of it is getting applied in the query:

?q=(((c_is_asset_b:(True)^0.01 AND (c_item_part_number_lower_s:(*systemkit*) OR c_title_lower_s:(*systemkit*) OR c_keywords_t:(*systemkit*) OR c_file_type_s:(*systemkit*) OR c_aggregated_search_fields_s:(*systemkit*) OR (c_item_part_number_lower_s:(*systemkit*) OR c_title_lower_s:(*systemkit*) OR c_keywords_t:(*systemkit*) OR c_file_type_s:(*systemkit*) OR c_aggregated_search_fields_s:(*systemkit*)) OR (title_t:(systemkit~100000))^2.5 OR (summary_t:(systemkit~100000))^1.5 OR _content:(systemkit~100000))) OR ((-c_is_asset_b:(True)  *:*)^9999 AND (c_item_part_number_lower_s:(*systemkit*) OR c_title_lower_s:(*systemkit*) OR c_keywords_t:(*systemkit*) OR c_file_type_s:(*systemkit*) OR c_aggregated_search_fields_s:(*systemkit*) OR (c_item_part_number_lower_s:(*systemkit*) OR c_title_lower_s:(*systemkit*) OR c_keywords_t:(*systemkit*) OR c_file_type_s:(*systemkit*) OR c_aggregated_search_fields_s:(*systemkit*)) OR (title_t:(systemkit~100000))^2.5 OR (summary_t:(systemkit~100000))^1.5 OR _content:(systemkit~100000)))) AND _val_:("recip(ms(NOW, c_date_tdt), 3.16e-11, 100, 1.8)"))&start=0&rows=100&fq=((((-c_alltemplates_sm:(b906556e0ab94174952026c282933569)  *:*) OR end_date_tdt:[2021-09-13T17:25:05.524Z TO *] OR start_date_tdt:[2021-09-13T17:25:05.524Z TO *]) AND c_searchable_b:(True)) AND _language:(en))&fq=_indexname:(sitecore_web_index)&facet=true&facet.field=c_locations_sm&f.c_locations_sm.facet.mincount=1&facet.field=c_architectures_sm&f.c_architectures_sm.facet.mincount=1&facet.field=c_topics_sm&f.c_topics_sm.facet.mincount=1&facet.field=c_content_type_s&f.c_content_type_s.facet.mincount=1&facet.field=c_file_type_s&f.c_file_type_s.facet.mincount=1&wt=xml

(there is some boosting in the Title and Summary, but not on the Is_Asset field that I'm trying to boost)

sehe
  • 374,641
  • 47
  • 450
  • 633
Erica Stockwell-Alpert
  • 4,624
  • 10
  • 63
  • 130

2 Answers2

0

It turns out the issue was that boosting does not work on boolean fields. I changed the IsAsset field to a string ("true" or "false") and was then able to implement boosting

var isAssetPredicate = PredicateBuilder.True<T>().And(predicate).And(x => x.IsAssetStr.Equals("true").Boost(0.001f));
var isPagePredicate = PredicateBuilder.True<T>().And(predicate).And(x => x.IsAssetStr.Equals("false").Boost(999f));
Erica Stockwell-Alpert
  • 4,624
  • 10
  • 63
  • 130
-1

Boosting SOLR queries does not work in sitecore versions 9.1-9.3. See below from sitecore website:

https://doc.sitecore.com/en/developers/93/platform-administration-and-architecture/search-result-boosting.html

Search result boosting works in Solr version 6.6 or earlier, but Solr changed the implementation in Solr 7, and later versions. Therefore, search result boosting is broken in Sitecore 9.1, 9.2, and 9.3.

Dean O'Brien
  • 335
  • 2
  • 11