我正在为客户的 Sitecore 项目之一开发全局搜索查询。要求是通过2种方式进行搜索:
我使用
PredicateBuilder
中的 Sitecore.ContentSearch.Linq
并编写了以下代码,我使用 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();
现在我需要在提升时按日期字段对它们进行排序。就像从 Boost(5f) 返回的项目一样,这些项目将按其更新日期降序排列。但在应用增强后,即使对于相同的增强项目,我也会得到不同的分数,这是预期的。我需要相同的提升值的恒定分数,以便我可以在按分数排序后按更新日期排序。我在 Solr 查询中看到
^=
关键字用于持续评分。有什么方法可以使用Sitecore.ContentSearch.Linq
来应用它吗?我想在不进行任何内存操作的情况下实现它。
恐怕无法通过
Sitecore.ContentSearch.Linq
和对 Solr 的单个请求来实现这一点。
我必须说,结合增强和自定义排序的复杂逻辑通常会让网站用户和内容编辑者感到困惑和难以理解。 但如果你确实想实现这个场景,最好的方法是将其分成两个 Solr 查询:
UpdatedDate
排序。var exactMatchResults = context.GetQueryable<GlobalSearchResultModel>()
.Where(finalPredicate.And(searchKeywordPredicate))
.OrderByDescending(x => x.UpdatedDate)
.ToList();
var exactMatchResults = context.GetQueryable<GlobalSearchResultModel>()
.Where(finalPredicate.And(splittedKeywordPredicate))
.ToList();