solr Sitecore.ContentSearch.Linq的常量分数查询

w7t8yxp5  于 2023-08-04  发布在  Solr
关注(0)|答案(1)|浏览(155)

我正在为客户的Sitecore项目之一开发全局搜索查询。要求通过2种方式进行搜索
1.与搜索关键字和标题完全匹配。(第一优先级)
1.必须拆分搜索关键字,并检查是否每个吐出的关键字都存在于标题中。(第二优先级)
我使用Sitecore.ContentSearch.Linq中的predicatebuilder并开发了以下代码。我使用了Boost方法来设置优先级,它工作正常

private Expression<Func<GlobalSearchResultModel, bool>> GetSearchResultsPredicate(string keyword)
    {
        var finalPredicate = PredicateBuilder.True<GlobalSearchResultModel>();
        var searchKeywordPredicate = PredicateBuilder.False<GlobalSearchResultModel>();
        var splittedKeywordPredicate = PredicateBuilder.True<GlobalSearchResultModel>();
        
        if (!string.IsNullOrEmpty(keyword))
        {
            var searchKeyword = keyword;
            var splittedKeywords = searchKeyword.Split(' ').Take(10).ToList();
            ID homeTemplateId = Templates.GlobalSearch.HomeTemplateId;
            ID announcementListingId = Templates.GlobalSearch.AnnouncementListingId;
            finalPredicate = finalPredicate.And(x => (x.Paths.Contains(homeTemplateId)
                                                    || x.Paths.Contains(announcementListingId)
                                                    )
                                                    && x.LatestVerion && !x.ExcludeFromSearch
                                                    && !(String.IsNullOrEmpty(x.Title) && String.IsNullOrEmpty(x.AnnouncementTitle)));

            searchKeywordPredicate = searchKeywordPredicate.Or(x => x.Title.Equals(searchKeyword).Boost(5f));

            foreach (var splittedKeyword in splittedKeywords)
            {
                splittedKeywordPredicate = splittedKeywordPredicate.And(x => x.Title.Contains(splittedKeyword).Boost(3f));
            }

            
            finalPredicate = finalPredicate.And(searchKeywordPredicate.Or(splittedKeywordPredicate));
        }
        return finalPredicate;
    }

字符串
使用以下命令检索结果

var result = context.GetQueryable<GlobalSearchResultModel>()
                                .Where(GetSearchResultsPredicate(searchKey))
                                .ToList();


现在,我需要按boosting上的日期字段对它们进行排序。就像从Boost(5 f)返回的项一样,将按它们的UpdatedDate降序排列。但在应用升压后,即使是相同的升压项目,我有不同的分数,这是预期的。我需要一个恒定的分数相同的提升值,这样我就可以order的UpdatedDate后,按分数排序。我在Solr查询中看到^=关键字用于常量评分。有没有办法使用Sitecore.ContentSearch.Linq来应用它?我想在不做任何内存操作的情况下实现它。
感谢您提供解决方案/建议。

qnzebej0

qnzebej01#

恐怕用Sitecore.ContentSearch.Linq和对Solr的单个请求是不可能实现这一点的。
我必须说,对于网站用户和内容编辑来说,结合了提升和自定义排序的复杂逻辑通常是令人困惑和难以理解的。但是如果你确实想实现这个场景,最好的方法是将它分成两个Solr查询:
1.获取精确匹配结果并按UpdatedDate排序。

var exactMatchResults = context.GetQueryable<GlobalSearchResultModel>()
                                .Where(finalPredicate.And(searchKeywordPredicate))
                                .OrderByDescending(x => x.UpdatedDate)
                                .ToList();

字符串
1.获取其余的结果,根据需要对它们进行排序(或保留默认的分数排序),并附加到第一个结果集:

var exactMatchResults = context.GetQueryable<GlobalSearchResultModel>()
                                .Where(finalPredicate.And(splittedKeywordPredicate))
                                .ToList();

相关问题