Как вывести новый контент в верхнюю часть результатов поиска с помощью Umbraco Examine?

У нас есть веб-сайт, созданный в Umbraco CMS, и я занимаюсь поиском по сайту. На веб-сайте есть раздел под названием "Новости", где регулярно публикуются обновления. При выводе результатов из раздела новостей (среди других страниц) я хочу, чтобы результаты отображались как можно раньше, например, если кто-то ищет "результаты экзамена", я хотел бы привести соответствующие страницы новостей, созданные в 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);
}

1 ответ

Решение

Поскольку другие могут столкнуться с той же проблемой и получить доступ к этому вопросу (через поиск), я публикую ответ на свой вопрос.

Я написал два обработчика событий, как показано ниже:

  1. Всякий раз, когда в Umbraco CMS публикуется новый контент, запускайте пересмотр индекса Examine.
  2. Когда индексатор Examine обнаружит псевдоним типа документа "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);
        }
    }
}
Другие вопросы по тегам