C# Solr boost 未应用于生成的查询

Posted

技术标签:

【中文标题】C# Solr boost 未应用于生成的查询【英文标题】:C# Solr boost not being applied to generated query 【发布时间】:2021-11-09 00:04:51 【问题描述】:

我将 Solr 7.5 与 Sitecore 9.2 一起使用。我有一些复杂的代码会生成一个搜索查询,我现在正在尝试应用提升来将页面项目优先于媒体资产(相关行从 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;
         

如您所见,我已经在多个地方进行了提升(我已经在谓词内和谓词外分别以及一起尝试过),但没有一个在查询中应用:

?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

(标题和摘要中有一些提升,但我试图提升的 Is_Asset 字段没有)

【问题讨论】:

【参考方案1】:

事实证明,问题在于提升不适用于布尔字段。我将 IsAsset 字段更改为字符串(“true”或“false”),然后能够实现提升

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));

【讨论】:

【参考方案2】:

提升 SOLR 查询在 sitecore 版本 9.1-9.3 中不起作用。请参阅 sitecore 网站的以下内容:

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

搜索结果提升在 Solr 6.6 或更早版本中工作,但 Solr 在 Solr 7 及更高版本中更改了实现。因此,搜索结果提升在 Sitecore 9.1、9.2 和 9.3 中被破坏。

【讨论】:

以上是关于C# Solr boost 未应用于生成的查询的主要内容,如果未能解决你的问题,请参考以下文章

有 SolrJ 查询生成器吗?

如何在控制台或文件中记录spring数据生成的solr查询

Solr总结

Solr系列漏洞复现

尽管 -isystem 仍生成警告

C#:SQL 查询生成器类