Not all pages with searched content is being returned.

Vote:
 

Hello,

We are having problems with search where there is content with the searched phrase, but its not showing it. Has anyone experienced this before and have any idea of what could be happening? It seems like content in blocks on the page are having the issue but there are many blocks that do appear on a search. Could the way we render some blocks be preventing content in that block from showing in the results?

Has anyone else experienced this?

#230759
Nov 12, 2020 15:37
Vote:
 

Can you provide a bit more context on what you are doing? Sample code?

#230761
Nov 12, 2020 17:00
Vote:
 
namespace Epi.Web.Controllers
{
    public class SearchPageController : BasePageController<SearchPage>
    {
        private readonly IClient searchClient;
        private readonly IFindUIConfiguration findUIConfiguration;
        private readonly IRequiredClientResourceList requiredClientResourceList;
        private readonly IVirtualPathResolver virtualPathResolver;

        public SearchPageController(IClient searchClient, IFindUIConfiguration findUIConfiguration, IRequiredClientResourceList requiredClientResourceList, IVirtualPathResolver virtualPathResolver)
        {
            this.searchClient = searchClient;
            this.findUIConfiguration = findUIConfiguration;
            this.requiredClientResourceList = requiredClientResourceList;
            this.virtualPathResolver = virtualPathResolver;
        }

        [ValidateInput(false)]
        public ViewResult Index(SearchPage currentPage, string q, string selectedAnalyzer)
        {
            var model = new SearchContentModel(currentPage)
            {
                PublicProxyPath = findUIConfiguration.AbsolutePublicProxyPath()
            };

            //detect if serviceUrl and/or defaultIndex is configured.
            model.IsConfigured = SearchIndexIsConfigured(EPiServer.Find.Configuration.GetConfiguration());

            if (model.IsConfigured && !string.IsNullOrWhiteSpace(model.Query))
            {
                var query = BuildQuery(model, selectedAnalyzer);

                //Create a hit specification to determine display based on values entered by an editor on the search page.
                var hitSpec = new HitSpecification
                {
                    HighlightTitle = model.CurrentPage.HighlightTitles,
                    HighlightExcerpt = model.CurrentPage.HighlightExcerpts,
                    // When HighlightExcerpt = true then minimum of ExcerptLength = 36
                    ExcerptLength = model.CurrentPage.HighlightExcerpts && model.ExcerptLength < 36 ? 36 : model.ExcerptLength
                };

                try
                {
                    model.Hits = query.GetResult(hitSpec);

                }
                catch (WebException wex)
                {
                    model.IsConfigured = wex.Status != WebExceptionStatus.NameResolutionFailure;
                }

                //Replace each excerpt text with TeaserText if page hit has valid teaser.
                if (model.Hits != null)
                {
                    foreach (UnifiedSearchHit hit in model.Hits)
                    {
                        var hitPage = hit.OriginalObjectGetter.Invoke() as BasePage;

                        if (hitPage != null && !string.IsNullOrEmpty(hitPage.TeaserText))
                        {
                            hit.Excerpt = hitPage.TeaserText;
                        }
                    }
                }
            }

            model.Analyzers = CreateAnalyzers(selectedAnalyzer);

            RequireClientResources();

            return View(model);
        }

        private IEnumerable<SelectListItem> CreateAnalyzers(string selected)
        {
            var items = new List<SelectListItem> { CreateSelectListItem("", "", selected) };

            items.AddRange(searchClient.Settings.Languages.Select(x => CreateSelectListItem(x.Name, x.FieldSuffix, selected)));

            return items;
        }

        private SelectListItem CreateSelectListItem(string name, string value, string selected)
        {
            return new SelectListItem { Text = name, Value = value, Selected = value == selected };
        }

        private ITypeSearch<ISearchContent> BuildQuery(SearchContentModel model, string selectedAnalyzer)
        {
            var language = searchClient.Settings.Languages.GetSupportedLanguage(selectedAnalyzer);

            var queryFor = language != null ?
                searchClient.UnifiedSearch(language) :
                searchClient.UnifiedSearch();

            var querySearch = string.IsNullOrEmpty(selectedAnalyzer) || language == null
                    ? queryFor.For(model.Query)
                    : queryFor.For(model.Query, x => x.Analyzer = language.Analyzer);

            if (model.UseAndForMultipleSearchTerms)
            {
                querySearch = querySearch.WithAndAsDefaultOperator();
            }

            var query = querySearch
                .UsingAutoBoost(TimeSpan.FromDays(30))
                //Include a facet whose value is used to show the total number of hits regardless of section.
                //The filter here is irrelevant but should match *everything*.
                .TermsFacetFor(x => x.SearchSection)
                .FilterFacet("AllSections", x => x.SearchSection.Exists())
                //Fetch the specific paging page.
                .Skip((model.PagingPage - 1) * model.CurrentPage.PageSize)
                .Take(model.CurrentPage.PageSize)
                //Allow editors (from the Find/Optimizations view) to push specific hits to the top 
                //for certain search phrases.
                .ApplyBestBets();

            // obey DNT
            var doNotTrackHeader = System.Web.HttpContext.Current.Request.Headers.Get("DNT");
            // Should not track when value equals 1
            if (doNotTrackHeader == null || doNotTrackHeader.Equals("0"))
            {
                query = query.Track();
            }

            //If a section filter exists (in the query string) we apply
            //a filter to only show hits from a given section.
            if (!string.IsNullOrWhiteSpace(model.SectionFilter))
            {
                query = query.FilterHits(x => x.SearchSection.Match(model.SectionFilter));
            }

            return query;
        }

        /// <summary>
        /// Checks if service url and index are configured
        /// </summary>
        /// <param name="configuration">Find configuration</param>
        /// <returns>True if configured, false otherwise</returns>
        private bool SearchIndexIsConfigured(EPiServer.Find.Configuration configuration)
        {
            return (!configuration.ServiceUrl.IsNullOrEmpty()
                    && !configuration.ServiceUrl.Contains("YOUR_URI")
                    && !configuration.DefaultIndex.IsNullOrEmpty()
                    && !configuration.DefaultIndex.Equals("YOUR_INDEX"));
        }

        /// <summary>
        /// Requires the client resources used in the view.
        /// </summary>
        private void RequireClientResources()
        {
            // jQuery.UI is used in autocomplete example.
            // Add jQuery.UI files to existing client resource bundles or load it from CDN or use any other alternative library.
            // We use local resources for demo purposes without Internet connection.
            requiredClientResourceList.RequireStyle(virtualPathResolver.ToAbsolute("~/Static/css/jquery-ui.css"));
            requiredClientResourceList.RequireScript(virtualPathResolver.ToAbsolute("~/Static/js/jquery-ui.js")).AtFooter();
        }
    }
}

The problems seem to happen mostly with some blocks in the pages, they're not having the text within them be found when that text gets searched.

This isnt happening on every block, only some.

Here is our searchController code: 

namespace Epi.Web.Controllers
{
    public class SearchPageController : BasePageController<SearchPage>
    {
        private readonly IClient searchClient;
        private readonly IFindUIConfiguration findUIConfiguration;
        private readonly IRequiredClientResourceList requiredClientResourceList;
        private readonly IVirtualPathResolver virtualPathResolver;

        public SearchPageController(IClient searchClient, IFindUIConfiguration findUIConfiguration, IRequiredClientResourceList requiredClientResourceList, IVirtualPathResolver virtualPathResolver)
        {
            this.searchClient = searchClient;
            this.findUIConfiguration = findUIConfiguration;
            this.requiredClientResourceList = requiredClientResourceList;
            this.virtualPathResolver = virtualPathResolver;
        }

        [ValidateInput(false)]
        public ViewResult Index(SearchPage currentPage, string q, string selectedAnalyzer)
        {
            var model = new SearchContentModel(currentPage)
            {
                PublicProxyPath = findUIConfiguration.AbsolutePublicProxyPath()
            };

            //detect if serviceUrl and/or defaultIndex is configured.
            model.IsConfigured = SearchIndexIsConfigured(EPiServer.Find.Configuration.GetConfiguration());

            if (model.IsConfigured && !string.IsNullOrWhiteSpace(model.Query))
            {
                var query = BuildQuery(model, selectedAnalyzer);

                //Create a hit specification to determine display based on values entered by an editor on the search page.
                var hitSpec = new HitSpecification
                {
                    HighlightTitle = model.CurrentPage.HighlightTitles,
                    HighlightExcerpt = model.CurrentPage.HighlightExcerpts,
                    // When HighlightExcerpt = true then minimum of ExcerptLength = 36
                    ExcerptLength = model.CurrentPage.HighlightExcerpts && model.ExcerptLength < 36 ? 36 : model.ExcerptLength
                };

                try
                {
                    model.Hits = query.GetResult(hitSpec);

                }
                catch (WebException wex)
                {
                    model.IsConfigured = wex.Status != WebExceptionStatus.NameResolutionFailure;
                }

                //Replace each excerpt text with TeaserText if page hit has valid teaser.
                if (model.Hits != null)
                {
                    foreach (UnifiedSearchHit hit in model.Hits)
                    {
                        var hitPage = hit.OriginalObjectGetter.Invoke() as BasePage;

                        if (hitPage != null && !string.IsNullOrEmpty(hitPage.TeaserText))
                        {
                            hit.Excerpt = hitPage.TeaserText;
                        }
                    }
                }
            }

            model.Analyzers = CreateAnalyzers(selectedAnalyzer);

            RequireClientResources();

            return View(model);
        }

        private IEnumerable<SelectListItem> CreateAnalyzers(string selected)
        {
            var items = new List<SelectListItem> { CreateSelectListItem("", "", selected) };

            items.AddRange(searchClient.Settings.Languages.Select(x => CreateSelectListItem(x.Name, x.FieldSuffix, selected)));

            return items;
        }

        private SelectListItem CreateSelectListItem(string name, string value, string selected)
        {
            return new SelectListItem { Text = name, Value = value, Selected = value == selected };
        }

        private ITypeSearch<ISearchContent> BuildQuery(SearchContentModel model, string selectedAnalyzer)
        {
            var language = searchClient.Settings.Languages.GetSupportedLanguage(selectedAnalyzer);

            var queryFor = language != null ?
                searchClient.UnifiedSearch(language) :
                searchClient.UnifiedSearch();

            var querySearch = string.IsNullOrEmpty(selectedAnalyzer) || language == null
                    ? queryFor.For(model.Query)
                    : queryFor.For(model.Query, x => x.Analyzer = language.Analyzer);

            if (model.UseAndForMultipleSearchTerms)
            {
                querySearch = querySearch.WithAndAsDefaultOperator();
            }

            var query = querySearch
                .UsingAutoBoost(TimeSpan.FromDays(30))
                //Include a facet whose value is used to show the total number of hits regardless of section.
                //The filter here is irrelevant but should match *everything*.
                .TermsFacetFor(x => x.SearchSection)
                .FilterFacet("AllSections", x => x.SearchSection.Exists())
                //Fetch the specific paging page.
                .Skip((model.PagingPage - 1) * model.CurrentPage.PageSize)
                .Take(model.CurrentPage.PageSize)
                //Allow editors (from the Find/Optimizations view) to push specific hits to the top 
                //for certain search phrases.
                .ApplyBestBets();

            // obey DNT
            var doNotTrackHeader = System.Web.HttpContext.Current.Request.Headers.Get("DNT");
            // Should not track when value equals 1
            if (doNotTrackHeader == null || doNotTrackHeader.Equals("0"))
            {
                query = query.Track();
            }

            //If a section filter exists (in the query string) we apply
            //a filter to only show hits from a given section.
            if (!string.IsNullOrWhiteSpace(model.SectionFilter))
            {
                query = query.FilterHits(x => x.SearchSection.Match(model.SectionFilter));
            }

            return query;
        }

        /// <summary>
        /// Checks if service url and index are configured
        /// </summary>
        /// <param name="configuration">Find configuration</param>
        /// <returns>True if configured, false otherwise</returns>
        private bool SearchIndexIsConfigured(EPiServer.Find.Configuration configuration)
        {
            return (!configuration.ServiceUrl.IsNullOrEmpty()
                    && !configuration.ServiceUrl.Contains("YOUR_URI")
                    && !configuration.DefaultIndex.IsNullOrEmpty()
                    && !configuration.DefaultIndex.Equals("YOUR_INDEX"));
        }

        /// <summary>
        /// Requires the client resources used in the view.
        /// </summary>
        private void RequireClientResources()
        {
            // jQuery.UI is used in autocomplete example.
            // Add jQuery.UI files to existing client resource bundles or load it from CDN or use any other alternative library.
            // We use local resources for demo purposes without Internet connection.
            requiredClientResourceList.RequireStyle(virtualPathResolver.ToAbsolute("~/Static/css/jquery-ui.css"));
            requiredClientResourceList.RequireScript(virtualPathResolver.ToAbsolute("~/Static/js/jquery-ui.js")).AtFooter();
        }
    }
}
#230762
Edited, Nov 12, 2020 19:36
Vote:
 

Hi QRiley327,

Are all your blocks actually indexed? Have you read the documentation about indexing blocks in contentarea: https://world.episerver.com/documentation/developer-guides/search-navigation/Integration/cms-integration/Indexing-content-in-a-content-area/

So have you checked what kind of implementation you have for your blocks in the solution? Perhaps you just have not enabled indexing for some blocks (also possible to switch on and off per instance if you have that property on the block type which an editor then can toggle on and off).

#230795
Nov 13, 2020 18:29
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.