Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ben Hill 24 posts 114 karma points
    Jul 27, 2021 @ 11:29
    Ben Hill
    0

    Examine linking direct to a node

    Hi all

    We recently released a new component type on our website.

    It has been spotted that within the Examine search results there is a link directly into the component as well as the page it is on.

    What would be the best approach to exclude the direct link into the component from the search results?

    Here is the link that is showing:

    /need-help/prohibited-goods/components/item-list/

    Thank you all in advance Ben

  • Bjarne Fyrstenborg 1214 posts 3591 karma points MVP 5x c-trib
    Jul 27, 2021 @ 13:36
    Bjarne Fyrstenborg
    0

    Hi Ben

    You probably need to either exclude a specific NodeTypeAlias from the Examine results or add a property to one or more document types you want to exclude from the results.

  • Ben Hill 24 posts 114 karma points
    Jul 27, 2021 @ 13:46
    Ben Hill
    0

    Hi Bjarne

    Thank you for taking the time out to reply.

    I had already kinda gone down the route of adding the below to the ExamineIndex.config file

    <ExcludeNodeTypes>
              <add Name="Item list" />
          </ExcludeNodeTypes>
    

    I just haven't rebuilt the indexes yet as I wasn't sure if there is another approach.

    Would excluding the node type by name stop Examine returning the page where the node is added? Or would it just exclude the node from the search results?

    And in your opinion is the above the best approach?

    Thanks Ben

  • Bjarne Fyrstenborg 1214 posts 3591 karma points MVP 5x c-trib
    Jul 27, 2021 @ 14:02
    Bjarne Fyrstenborg
    0

    Ahh, I didn't notice it was related to v7, where you have to config files.

    You should be able to exclude the document type by it's alias, but I think the name shouldn't include a space.

    If have another node selecting this node type using a picker, I guess it returns a value for the specific property.

    Do you have a code snippet of the Examine quering and how the results are returned?

  • Ben Hill 24 posts 114 karma points
    Jul 27, 2021 @ 14:06
    Ben Hill
    0

    Hi Bjarne

    Just to clarify, are you referring to the code snippet that writes out the results in the view?

  • Bjarne Fyrstenborg 1214 posts 3591 karma points MVP 5x c-trib
    Jul 27, 2021 @ 14:10
    Bjarne Fyrstenborg
    0

    Hi Ben

    Yes, or in a Controller. Mainly the part doing the Examine query and maybe share to node structure in Umbraco :)

  • Ben Hill 24 posts 114 karma points
    Jul 27, 2021 @ 15:51
    Ben Hill
    0

    Hey Bjarne

    Here's the code from the partial view :-)

    @inherits UmbracoViewPage

    @using USNStarterKit.USNHelpers; @using Examine.SearchCriteria; @using Examine.LuceneEngine.SearchCriteria; @using Umbraco.Web; @using UmbracoExamine; @using Our.Umbraco.Vorto.Extensions; @using System.Text.RegularExpressions; @using System.Threading

    @{ UsnglobalSettings globalSettings = (UsnglobalSettings)Model.GlobalSettings; var currentCulture = Thread.CurrentThread.CurrentCulture.ToString();

    if (globalSettings.SearchResultsPage != null)
    {
        UsnsearchResultsPage searchResultsPage = (UsnsearchResultsPage)Model.Content;
    
        int pageSize = searchResultsPage.SearchResultsPageSize; // How many items per page
        int page; // The page we are viewing
        string originalSearchTerm = String.Empty;
        string searchTerm = String.Empty;
        bool searchError = false;
    
        if (!String.IsNullOrEmpty(Context.Request.QueryString["search_field"]))
        {
            ////Makes search query safe
            ////Match all characters that DO NOT (^) match (\w alphanumeric characters) and \s (white space and tab) and - (hyphen) and replace them with ""
            //originalSearchTerm = Request.QueryString["search_field"].Trim();
            //searchTerm = Regex.Replace(originalSearchTerm, @"[^\w\s-]", "");
    
            ////Match any white space character
            //searchTerm = Regex.Replace(searchTerm, @"\s+", " ");
    
            searchTerm = Context.Request.QueryString["search_field"].Trim().ToLowerInvariant();
        }
    
        if (!int.TryParse(Request.QueryString["page"], out page))
        {
            page = 1;
        }
    
        string examineSearcher = "ExternalSearcher";
    
        if (currentCulture == "zh-HK" || currentCulture == "zh")
        {
            examineSearcher = "External_CN_Searcher";
        }
    
        Examine.Providers.BaseSearchProvider baseSearchProvider = ExamineManager.Instance.SearchProviderCollection[examineSearcher];
        IEnumerable<SearchResult> results;
        List<IPublishedContent> nodes = new List<IPublishedContent>();
        int totalNodes = 0;
        int totalPages;
    
        if (!String.IsNullOrEmpty(searchTerm))
        {
    
    
            var criteria = baseSearchProvider.CreateSearchCriteria(IndexTypes.Content, BooleanOperation.And);
            var siteRootId = Model.Content.Site();
    
            //Field added via USNRegisterEvents class.
            var examineQuery = criteria.Field("searchablePath", siteRootId.ToString());
            examineQuery.Not().Field("umbracoNaviHide", 1.ToString());
            examineQuery.And().Field("contents", searchTerm);
    
            //if (searchTerm.Contains(" "))
            //{
    
            //    var terms = searchTerm.Split(' ').Select(x => x.MultipleCharacterWildcard()).ToArray();
            //    //Search limited to 4 terms: ref maxClauseCount is set to 1024
            //    if (terms.Length > 4)
            //    {
            //        searchError = true;
            //    }
            //    else
            //    {
            //        examineQuery.And().GroupedOr(new List<string> { "contents" }, terms);
            //    }
            //}
            //else
            //{
            //    examineQuery.And().GroupedOr(new List<string> { "contents" }, searchTerm.MultipleCharacterWildcard());
            //}
    
            if (!searchError)
            {
                results = baseSearchProvider.Search(examineQuery.Compile());
    
                //create a list of nodes based on parent page.
                foreach (var item in results)
                {
                    var node = Umbraco.TypedContent(item.Fields["id"]);
    
                    if (node != null)
                    {
                        //Check if node found has a parent redirect template. If it does we want to find the first parent page.
                        if (node.GetTemplateAlias() == "USNParentRedirect")
                        {
                            node = node.Ancestors().First(x => x.GetTemplateAlias() != "USNParentRedirect");
                        }
    
                        if (node.IsVisible())
                        {
                            nodes.Add(node);
                        }
                    }
                }
    
                //remove duplicates
                nodes = nodes.GroupBy(x => x.Id).Select(y => y.First()).ToList();
    
                totalNodes = nodes.Count;
                totalPages = (int)Math.Ceiling(totalNodes / (double)pageSize);
    
                if (page > totalPages)
                {
                    page = totalPages;
                }
                else if (page < 1)
                {
                    page = 1;
                }
            }
        }
    
    
        if (searchError)
        {
            <p>@umbraco.library.GetDictionaryItem("USN Search Term Limit")</p>
        }
        if (totalNodes == 0)
        {
            <p>@umbraco.library.GetDictionaryItem("USN Search Results Nothing Found")</p>
            @Html.Partial("USNForms/USN_SearchForm", Model)
        }
        else
        {
            int pages = (int)Math.Ceiling(totalNodes / (double)pageSize);
    
            //Please note the dictionary item should have a {0} and {1} placeholder for string formatting.
            string searchResultsFeedback = umbraco.library.GetDictionaryItem("USN Search Results Feedback");
            searchResultsFeedback = String.Format(searchResultsFeedback, originalSearchTerm, totalNodes);
    
            <p>@Html.Raw(searchResultsFeedback)</p>
            @Html.Partial("USNForms/USN_SearchForm", Model)
    
            <div class="listing vertical search">
                @foreach (var item in nodes.Skip((page - 1) * pageSize).Take(pageSize))
                {
                    <div class="item">
                        <p class="heading"><a class="c3-text" href="@item.Url">@item.Name</a></p>
                        @if (item.HasVortoValue("metaDescription"))
                        {
                            <div class="text">@Html.Raw(umbraco.library.ReplaceLineBreaks(item.GetVortoValue<string>("metaDescription")))</div>
                        }
                        <p class="link">@umbraco.library.GetDictionaryItem("USN Search Results Link Label") <a href="@item.Url">@item.Url</a></p>
                    </div>
                }
            </div>
    
            if (pages > 1)
            {
                <!-- PAGINATION -->
                @Html.Partial("USNMiscPageElements/USN_Paging", new ViewDataDictionary { { "totalPageCount", pages } })
                <!--// PAGINATION -->
            }
        }
    }
    

    }

  • Bjarne Fyrstenborg 1214 posts 3591 karma points MVP 5x c-trib
    Jul 27, 2021 @ 17:25
    Bjarne Fyrstenborg
    0

    Hi Ben

    Okay, you have this part to find get node based on a selected template.

    //Check if node found has a parent redirect template. If it does we want to find the first parent page.
    if (node.GetTemplateAlias() == "USNParentRedirect")
    {
        node = node.Ancestors().First(x => x.GetTemplateAlias() != "USNParentRedirect");
    }
    

    Not sure what the specific purpose of this is. I would probably use Content Picker, MNTP (configurated as single picker - max = 1) or Multi URL Picker https://our.umbraco.com/packages/backoffice-extensions/multi-url-picker/ (this is include in Umbraco core in newer versions of Umbraco).

    Then you would be able to select exact node to redirect to

    var redirect = node.GetPropertyValue<string>("myRedirect");
    if (!string.isNullOrEmpty(redirect))
    {
        node = Umbraco.TypedContent(redirect);
    }
    

    It is worth mentioning that you could use Content Picker and alias umbracoRedirect which would automatically handle a redirect when accessing that node. https://our.umbraco.com/Documentation/Reference/Routing/routing-properties#umbracoredirect

    You could also consider call the ConvertSearchResultToPublishedContent extension method.

     results = baseSearchProvider.Search(examineQuery.Compile()).ConvertSearchResultToPublishedContent(UmbracoContext.Current.ContentCache);
    

    which would return the Examine results as IEnumerable<IPublishedContent>.

    It should then also be possible to filter the collection on umbracoNaviHide using .IsVisible() extension.

     results = results.Where(x => x.IsVisible());
    

    However it would be better to include this as part of you Examine query (filter/exclude as much as possible here), which you actually do here:

    examineQuery.Not().Field("umbracoNaviHide", 1.ToString());
    

    But since you have the second lookup, you probably need it again. Some of these approaches should work as well.

    node = node.Ancestors().FirstOrDefault(x => x.GetTemplateAlias() != "USNParentRedirect" && x.IsVisible());
    
    node = Umbraco.TypedContent(redirect);
    if (node != null && node.IsVisible())
    {
        // Do something
    }
    

    Also note the Search() method y default only return 500 results. You can increase that e.g. Search(examineQuery.Compile(), maxResults: 1000) but not recommended to increase it too much. If the project has a lot of content nodes it probably need to return a paged result instead.

  • Ben Hill 24 posts 114 karma points
    Aug 02, 2021 @ 08:04
    Ben Hill
    0

    Hi Bjarne

    Sorry for the late reply, so great stuff in there and I will take a look over to see what options I can utilise.

    Thanks again

Please Sign in or register to post replies

Write your reply to:

Draft