Copied to clipboard

Flag this post as spam?

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


  • Adriano Fabri 458 posts 1601 karma points
    Mar 29, 2017 @ 16:20
    Adriano Fabri
    0

    Examin Search and empty querystring

    Hi to all, my actual result partial view can show results only if the querystring isn't empty (or null).

    Now I need to extend this search to show all nodes, when I have an empty querystring.

    I tried to enable wildcards and used * or ? but I always receive YSOD page.

    This is my actual code:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    
    @using Lucene.Net;
    @using Examine;
    @using Examine.LuceneEngine.SearchCriteria;
    @using USNStarterKit.USNBusinessLogic;
    
    @{
        int pageSize = 10; // How many items per page
        int page; // The page we are viewing
        string originalSearchTerm = "";
        string searchTerm = "";
    
        if (!String.IsNullOrEmpty(Context.Request.QueryString["q"]))
        {
            var regex = new System.Text.RegularExpressions.Regex(@"[^\w\s-]");
    
            originalSearchTerm = Request.QueryString["q"].Trim();
            searchTerm = regex.Replace(originalSearchTerm, "");
        }
    
        /* Set up parameters */
    
        if (!int.TryParse(Request.QueryString["page"], out page))
        {
            page = 1;
        }
    
        /* This is your basic query to select the nodes you want */
    
        Examine.Providers.BaseSearchProvider baseSearchProvider = Examine.ExamineManager.Instance.SearchProviderCollection["MyCustomSearcher"];
        IEnumerable<SearchResult> nodes = null;
        //ISearchResults nodes = null;
        Lucene.Net.Search.Searcher luceneSearcher = null;
        int totalNodes = 0;
        int totalPages = 0;
    
        if (!String.IsNullOrEmpty(searchTerm))
        {
            //nodes = baseSearchProvider.Search(searchTerm, true);
            var searchCriteria = Examine.ExamineManager.Instance.CreateSearchCriteria(Examine.SearchCriteria.BooleanOperation.Or);
    
            //Boost matches that contain all search terms higher
            var luceneStringNodeName = "nodeName:";
            luceneStringNodeName += "(+" + searchTerm.Replace(" ", " +") + ")^5 ";
            luceneStringNodeName += "nodeName:" + searchTerm;
    
            //Boost matches that contain all search terms higher
            var luceneStringBodyText = "bodyText:";
            luceneStringBodyText += "(+" + searchTerm.Replace(" ", " +") + ")^5 ";
            luceneStringBodyText += "bodyText:" + searchTerm;
    
            var query = searchCriteria.RawQuery(luceneStringNodeName + " OR " + luceneStringBodyText);
    
            var results = baseSearchProvider.Search(query); //.OrderByDescending(x => x.Score)
            luceneSearcher = ((Examine.LuceneEngine.SearchResults)results).LuceneSearcher;
            nodes = results.OrderByDescending(x => x.Score);
    
            totalNodes = nodes.Count();
            totalPages = (int)Math.Ceiling((double)totalNodes / (double)pageSize);
    
            /* Bounds checking */
    
            if (page > totalPages)
            {
                page = totalPages;
            }
            else if (page < 1)
            {
                page = 1;
            }
        }
    
        if (totalNodes == 0)
        {
        <p>Non sono stati trovati risultati</p>
        }
        else
        {
        <div class="elencoPaginato">
            @foreach (var item in nodes.OrderByDescending(f => f.Fields["date"]).Skip((page - 1) * pageSize).Take(pageSize))
            {
                string imgURL = string.Empty;
                if (item.Fields.ContainsKey("listImages"))
                {
                    var elencoImmagini = item.Fields["listImages"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    var image = Umbraco.Media(elencoImmagini[0]);
                    imgURL = image.Url;
                }
                else
                {
                    imgURL = "/media/1015/logo.png";
                }
    
                <section class="search-result-item">
                    <a href="@Umbraco.NiceUrl(Convert.ToInt32(@item.Fields["id"]))" title="@item.Fields["nodeName"]" class="image-link">
                        <img src="@imgURL" alt="@item.Fields["nodeName"]" class="image" />
                    </a>
                    <div class="search-result-item-body">
                        <div class="row">
                            <div class="col-sm-12">
                                <h4 class="search-result-item-heading">
                                    <a href="@Umbraco.NiceUrl(Convert.ToInt32(@item.Fields["id"]))" title="@item.Fields["nodeName"]">@item.Fields["nodeName"]</a>
                                </h4>
                                @{
                                    DateTime articleDate = DateTime.Parse(item.Fields["date"].ToString());
                                    var annuncioType = item.Fields.ContainsKey("type") ? item.Fields["type"].ToString() : string.Empty;
                                    var annuncioPrezzo = item.Fields.ContainsKey("type") ? item.Fields["price"].ToString() : string.Empty;
                                }
                                <p class="info">
                                    @articleDate.ToString("dd/MM/yyyy") -
                                    <span class="@annuncioType.ToLower()">@annuncioType</span>
                                    <span class="prezzo-lista">&euro; @annuncioPrezzo</span>
                                </p>
                                @{ string fieldName = "bodyText";
                                    string searchHighlight = "";
    
                                    if (item.Fields.ContainsKey(fieldName))
                                    {
                                        string fieldValue = item.Fields[fieldName];
                                        searchHighlight = USNLuceneHelper.Instance.GetHighlight(fieldValue, fieldName, luceneSearcher, searchTerm);
    
                                        if (String.IsNullOrEmpty(searchHighlight))
                                        {
                                            searchHighlight = Umbraco.Truncate(fieldValue, 200).ToString();
                                        }
    
                                        <div data-truncate>@Html.Raw(searchHighlight)</div>
                                    }
                                }
                            </div>
                        </div>
                    </div>
                </section>
                                    }
        </div>
    
                @RenderPagination(page, totalNodes, pageSize, totalPages)
                                    }
    }
    
    
    @helper RenderPagination(int page, int postCount, int itemsPerPage, int totalPages)
    {
    int pages = (int)Math.Ceiling((double)postCount / (double)itemsPerPage);
    
    string url = Request.Url.ToString();
    string lastUrl = url.ReplaceQueryStringItem("page", totalPages.ToString());
    string querystring = Request.Url.Query;
    
    int pagesPerGroup = 10;
    
    if (pages > 1)
    {
        <div class="text-align-center">
            <ul class="pagination pagination-sm">
                @*render prev link *@
                @if (page > 1)
                {
                    url = url.ReplaceQueryStringItem("page", (page - 1).ToString());
                    <li class="prev">
                        <a href="@url" aria-label="Previous" title="@umbraco.library.GetDictionaryItem("USN Listing Navigation Previous")"><i class="ion-chevron-left"></i><span class="hidden">@umbraco.library.GetDictionaryItem("USN Listing Navigation Previous")</span></a>
                    </li>
    
                    if (page > pagesPerGroup)
                    {
                        if (page % pagesPerGroup == 0)
                        {
                            url = url.ReplaceQueryStringItem("page", (page - pagesPerGroup).ToString());
                        }
                        else
                        {
                            url = url.ReplaceQueryStringItem("page", ((page / pagesPerGroup) * pagesPerGroup).ToString());
                        }
    
                        <li class="hidden-xs"><a href="@url">...</a></li>
                    }
                }
                @* render page links *@
                @{
                    int pagesCount = 0;
                    int startPage = 1;
    
    
                    if (page <= pagesPerGroup)
                    {
                        startPage = 1;
                    }
                    else if (page % pagesPerGroup > 0)
                    {
                        startPage = page - (page % pagesPerGroup) + 1;
                    }
                    else if (page % pagesPerGroup == 0)
                    {
                        startPage = (page - pagesPerGroup) + 1;
                    }
    
                    for (int i = startPage; i < pages + 1; i++)
                    {
                        if (pagesCount == pagesPerGroup)
                        {
                            break;
                        }
                        url = url.ReplaceQueryStringItem("page", i.ToString());
                        string pageClass = i == page ? "active" : string.Empty;
    
                        <li class="hidden-xs @pageClass">
                            @if (page == i)
                            {
                            <a href="@url" class="disabled">@i<span class="sr-only">(current)</span></a>
                            }
                            else
                            {
                            <a href="@url">@i</a>
                            }
                        </li>
    
                        pagesCount += 1;
                    }
    
                }
                @{
    
                    int totalGroups = 0;
    
                    if (pages % pagesPerGroup == 0)
                    {
                        totalGroups = pages / pagesPerGroup;
                    }
                    else
                    {
                        totalGroups = pages / pagesPerGroup + 1;
                    }
    
                    int currentGroup = 0;
    
                    if (page % pagesPerGroup == 0)
                    {
                        currentGroup = page / pagesPerGroup;
                    }
                    else
                    {
                        currentGroup = page / pagesPerGroup + 1;
                    }
    
    
                    if (totalGroups != currentGroup)
                    {
    
                        if (page % pagesPerGroup == 0)
                        {
                            url = url.ReplaceQueryStringItem("page", (page + 1).ToString());
                        }
                        else
                        {
                            int liPageNumber = (((page / pagesPerGroup) + 1) * pagesPerGroup) + 1;
                            url = url.ReplaceQueryStringItem("page", liPageNumber.ToString());
                        }
    
                        <li class="hidden-xs">
                            <a href="@url">...</a>
                        </li>
                        <li class="hidden-xs">
                            <a href="@lastUrl">@totalPages</a>
                        </li>
                    }
                }
    
                @if (page < Math.Ceiling((double)postCount / itemsPerPage))
                {
                    url = url.ReplaceQueryStringItem("page", (page + 1).ToString());
                    @* render next link *@
                    <li class="next">
                        <a href="@url" aria-label="Next" title="@umbraco.library.GetDictionaryItem("USN Listing Navigation Next")">
                            <span class="hidden">@umbraco.library.GetDictionaryItem("USN Listing Navigation Next")</span>
                            <i class="ion-chevron-right"></i>
                        </a>
                    </li>
                }
            </ul>
        </div>
      }
    }
    

    How can I change this code to show all nodes when I receive an empty querystring?

    Thanks for support.

    Adriano

  • Marcin Zajkowski 112 posts 585 karma points MVP 6x c-trib
    Mar 29, 2017 @ 23:55
    Marcin Zajkowski
    0

    Hey Adriano,

    you should just implement case when your searchQuery is null or empty, so you need else block and code for retrieving all nodes (baseSearchProvider or your implementation without any specific boosting, filtering etc.).

    Your code is filling nodes collection only if searchQuery is not null or empty.

    Just remind to refactor it a little bit to not duplicate the same chunks of code.

  • Adriano Fabri 458 posts 1601 karma points
    Mar 30, 2017 @ 09:44
    Adriano Fabri
    0

    Thank you Marcin for your answer...I already tried to implement an else block, but I didn't found what write in the "searchTerm" string or how to change code to get all results.

    For example I tried with "*", and with "?" but I receive always an YSOD page with this error:

    Lucene.Net.QueryParsers.ParseException: '*' or '?' not allowed as first character in WildcardQuery

    Do you help me?

    I have not big experience with examine.

    Thanks Adriano

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Mar 30, 2017 @ 10:13
    Ismail Mayat
    0

    Adriano,

    Couple of things:

    nodes = results.OrderByDescending(x => x.Score);
    

    Its already sorted by score you are adding extra over head by sorting again with linq. You do not need this.

    Also not sure why you are using raw query and all the string manipulation when you can do it with the examine fluent api.

    Anyhow to get all content when no query then in the else do:

    var searchCriteria = baseSearchProvider.CreateSearchCriteria(IndexTypes.Content);
    

    var results = baseSearchProvider.Search(searchCriteria);

  • Adriano Fabri 458 posts 1601 karma points
    Mar 30, 2017 @ 10:40
    Adriano Fabri
    0

    I'm using this results_page code because is a part of uSkinned...so...I only would to add my custom code to get all results when user don't write any search terms.

    With your indications, I change my code:

    try
        {
            if (!String.IsNullOrEmpty(searchTerm))
            {
                //nodes = baseSearchProvider.Search(searchTerm, true);
                var searchCriteria = Examine.ExamineManager.Instance.CreateSearchCriteria(Examine.SearchCriteria.BooleanOperation.Or);
    
                //Boost matches that contain all search terms higher
                var luceneStringNodeName = "nodeName:";
                luceneStringNodeName += "(+" + searchTerm.Replace(" ", " +") + ")^5 ";
                luceneStringNodeName += "nodeName:" + searchTerm;
    
                //Boost matches that contain all search terms higher
                var luceneStringBodyText = "bodyText:";
                luceneStringBodyText += "(+" + searchTerm.Replace(" ", " +") + ")^5 ";
                luceneStringBodyText += "bodyText:" + searchTerm;
    
                var query = searchCriteria.RawQuery(luceneStringNodeName + " OR " + luceneStringBodyText);
    
                var results = baseSearchProvider.Search(query); //.OrderByDescending(x => x.Score)
                luceneSearcher = ((Examine.LuceneEngine.SearchResults)results).LuceneSearcher;
                nodes = results.OrderByDescending(x => x.Score);
            }
            else
            {
                var searchCriteria = baseSearchProvider.CreateSearchCriteria(UmbracoExamine.IndexTypes.Content);
                var results = baseSearchProvider.Search(searchCriteria);
                luceneSearcher = ((Examine.LuceneEngine.SearchResults)results).LuceneSearcher;
                nodes = results.OrderByDescending(x => x.Score);
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
    

    The actual result is: NO DOCUMENT FOUND.

    But if you see the screenshot, you can see that there are 7 nodes in the Index.

    My Custom Index

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Mar 30, 2017 @ 10:50
    Ismail Mayat
    0

    Adriano,

    Before line

     var results = baseSearchProvider.Search(searchCriteria);
    

    Can you do searchCriteria.ToString() then paste back here the output. I want to see the generated query.

    Regards

    Ismail

  • Adriano Fabri 458 posts 1601 karma points
    Mar 30, 2017 @ 11:10
    Adriano Fabri
    0

    This is the output.

    { SearchIndexType: content, LuceneQuery: }

    Adriano

  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Mar 30, 2017 @ 11:14
    Dan Diplo
    102

    Instead of using Examine to bring back all pages in the site, couldn't you just use a standard Umbraco query? eg.

    var allPages = Model.Content.Ancestor(1).DescendantsOrSelf();
    
  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Mar 30, 2017 @ 11:15
    Ismail Mayat
    0

    Dan,

    Good point.

  • Adriano Fabri 458 posts 1601 karma points
    Mar 30, 2017 @ 12:47
    Adriano Fabri
    0

    Hi Dan...good suggestion. I was so determined to want to resolve the problem with Examine that I haven't thought at this solution :-)

    Thank you very much.

    I will take this solution!

    Thank yout to all Bye

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Mar 30, 2017 @ 11:14
    Ismail Mayat
    0

    Adriano,

    Argghh. Ok I thought that would work. The quickest thing then would be todo:

    var searchCriteria = baseSearchProvider.CreateSearchCriteria(UmbracoExamine.IndexTypes.Content);
    

    var query = criteria.GroupedOr(new List

    Replace nodetype1 2 with your node types. Then do

    var results = baseSearchProvider.Search(query);

Please Sign in or register to post replies

Write your reply to:

Draft