如何使用 Umbraco Examine 将更新的内容置于搜索结果的顶部?
How to bring newer content at the top of search results using Umbraco Examine?
我们在 Umbraco CMS 中创建了一个网站,我正在开发网站搜索功能。网站中有一个名为 "news" 的部分,其中发布定期更新。在列出新闻部分(以及其他页面)的结果时,我想更早地在结果中显示最新内容,例如如果有人正在搜索 "exam results",我想将 2018 年创建的匹配新闻页面早于 2017 年创建的页面等。是否有提升(查询时间或索引时间)以便提升最新页面的方法?
以下是我到目前为止编写的代码:
var page = 1;
var pageSize = 5;
if (Request.QueryString["q"] != null)
searchQuery = Request.QueryString["q"];
if (Request.QueryString["page"] != null)
Int32.TryParse(Request.QueryString["page"], out page);
ISearchResults searchResults = null;
BaseSearchProvider searcher = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"];
var headerFields = new[] { "contentTitle", "metaTags", "metaDescription", "nodeName" };
var contentFields = new[] { "contentDescription", "mainBody" };
var criteria = searcher.CreateSearchCriteria(IndexTypes.Content, BooleanOperation.Or);
var searchTerm = string.IsNullOrEmpty(Request["q"]) ? string.Empty : Request["q"];
if (searchTerm != string.Empty)
{
searchTerm = searchTerm.MakeSearchQuerySafe();
if (searchTerm.Length > 0)
{
searchTerm = searchTerm.Trim();
}
var examineQuery = criteria.GroupedOr(headerFields, searchTerm.Boost(100));
examineQuery.Or().GroupedOr(contentFields, searchTerm.Boost(50));
if (searchTerm.Contains(" "))
{
examineQuery.Or().GroupedOr(headerFields, searchTerm.RemoveStopWords().Split(' ').Select(x => x.MultipleCharacterWildcard().Value.Boost(10)).ToArray());
examineQuery.Or().GroupedOr(contentFields, searchTerm.RemoveStopWords().Split(' ').Select(x => x.MultipleCharacterWildcard()).ToArray());
}
searchResults = searcher.Search(examineQuery.Compile(), maxResults: pageSize * page);
}
由于其他人可能会遇到同样的问题并(通过搜索)找到这个问题,所以我发布了我自己的问题的答案。
我写了两个事件处理程序如下:
- 每当 Umbraco CMS 中发布新内容时,都会触发检查索引重建。
- 当检查索引器遇到文档类型别名 "newsArticle" 时,相对于上次更新日期降低文档。
事件处理代码如下:
public class ExamineEvents : Umbraco.Core.ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var indexer = (UmbracoContentIndexer)ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"];
indexer.DocumentWriting += Indexer_DocumentWriting;
Umbraco.Core.Services.ContentService.Published += ContentService_Published;
}
private void ContentService_Published(Umbraco.Core.Publishing.IPublishingStrategy sender, Umbraco.Core.Events.PublishEventArgs<Umbraco.Core.Models.IContent> e)
{
ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"].RebuildIndex();
}
private void Indexer_DocumentWriting(object sender, DocumentWritingEventArgs e)
{
//if it is a 'news article' doc type then > BOOST it DOWN - the older the article, the lower the boost value
if (e.Fields.ContainsKey("nodeTypeAlias") && e.Fields["nodeTypeAlias"] == "newsArticle")
{
float boostValue = 1f;
const string umbDateField = "updateDate";
if (e.Fields.ContainsKey(umbDateField))
{
DateTime updateDate = DateTime.Parse(e.Fields[umbDateField]);
var daysInBetween = Math.Ceiling((DateTime.Now - updateDate).TotalDays + 1); // +1 to avoid 0 days
boostValue = (float) (1 / daysInBetween);
}
e.Document.SetBoost(boostValue);
}
}
}
我们在 Umbraco CMS 中创建了一个网站,我正在开发网站搜索功能。网站中有一个名为 "news" 的部分,其中发布定期更新。在列出新闻部分(以及其他页面)的结果时,我想更早地在结果中显示最新内容,例如如果有人正在搜索 "exam results",我想将 2018 年创建的匹配新闻页面早于 2017 年创建的页面等。是否有提升(查询时间或索引时间)以便提升最新页面的方法?
以下是我到目前为止编写的代码:
var page = 1;
var pageSize = 5;
if (Request.QueryString["q"] != null)
searchQuery = Request.QueryString["q"];
if (Request.QueryString["page"] != null)
Int32.TryParse(Request.QueryString["page"], out page);
ISearchResults searchResults = null;
BaseSearchProvider searcher = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"];
var headerFields = new[] { "contentTitle", "metaTags", "metaDescription", "nodeName" };
var contentFields = new[] { "contentDescription", "mainBody" };
var criteria = searcher.CreateSearchCriteria(IndexTypes.Content, BooleanOperation.Or);
var searchTerm = string.IsNullOrEmpty(Request["q"]) ? string.Empty : Request["q"];
if (searchTerm != string.Empty)
{
searchTerm = searchTerm.MakeSearchQuerySafe();
if (searchTerm.Length > 0)
{
searchTerm = searchTerm.Trim();
}
var examineQuery = criteria.GroupedOr(headerFields, searchTerm.Boost(100));
examineQuery.Or().GroupedOr(contentFields, searchTerm.Boost(50));
if (searchTerm.Contains(" "))
{
examineQuery.Or().GroupedOr(headerFields, searchTerm.RemoveStopWords().Split(' ').Select(x => x.MultipleCharacterWildcard().Value.Boost(10)).ToArray());
examineQuery.Or().GroupedOr(contentFields, searchTerm.RemoveStopWords().Split(' ').Select(x => x.MultipleCharacterWildcard()).ToArray());
}
searchResults = searcher.Search(examineQuery.Compile(), maxResults: pageSize * page);
}
由于其他人可能会遇到同样的问题并(通过搜索)找到这个问题,所以我发布了我自己的问题的答案。
我写了两个事件处理程序如下:
- 每当 Umbraco CMS 中发布新内容时,都会触发检查索引重建。
- 当检查索引器遇到文档类型别名 "newsArticle" 时,相对于上次更新日期降低文档。
事件处理代码如下:
public class ExamineEvents : Umbraco.Core.ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var indexer = (UmbracoContentIndexer)ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"];
indexer.DocumentWriting += Indexer_DocumentWriting;
Umbraco.Core.Services.ContentService.Published += ContentService_Published;
}
private void ContentService_Published(Umbraco.Core.Publishing.IPublishingStrategy sender, Umbraco.Core.Events.PublishEventArgs<Umbraco.Core.Models.IContent> e)
{
ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"].RebuildIndex();
}
private void Indexer_DocumentWriting(object sender, DocumentWritingEventArgs e)
{
//if it is a 'news article' doc type then > BOOST it DOWN - the older the article, the lower the boost value
if (e.Fields.ContainsKey("nodeTypeAlias") && e.Fields["nodeTypeAlias"] == "newsArticle")
{
float boostValue = 1f;
const string umbDateField = "updateDate";
if (e.Fields.ContainsKey(umbDateField))
{
DateTime updateDate = DateTime.Parse(e.Fields[umbDateField]);
var daysInBetween = Math.Ceiling((DateTime.Now - updateDate).TotalDays + 1); // +1 to avoid 0 days
boostValue = (float) (1 / daysInBetween);
}
e.Document.SetBoost(boostValue);
}
}
}