Copied to clipboard

Flag this post as spam?

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


  • Shawn Calvert 5 posts 94 karma points
    1 week ago
    Shawn Calvert
    0

    Two solutions for Examine word and phrase search, both missing something

    First of all, thank you to anyone on this forum who has posted anything on using Examine in Umbraco. I've been trying to figure out something that ended up taking way more time to figure out because I'm green, and am still not quite there -- a search on either a word or phrase, weighted by score.

    The first one uses Raw Lucern Query that is in the Examining Examine article:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @using Examine;
    @using Examine.SearchCriteria;
    @using Examine.LuceneEngine.SearchCriteria;
    
    @{
        if (!string.IsNullOrEmpty(Request.QueryString["query"]))
        {
            var searchString = Request.QueryString["query"];
            var Searcher = ExamineManager.Instance.SearchProviderCollection["ArticleSearcher"];
            var searchCriteria = Searcher.CreateSearchCriteria(BooleanOperation.Or);
            var term = searchString;
            var luceneString = "nodeName:";
            luceneString += "(+" + term.Replace(" ", " +") + ")^5 ";
            luceneString += "nodeName:" + term;
            var query = searchCriteria.RawQuery(luceneString);
            var searchResults = Searcher.Search(query).OrderByDescending(x => x.Score);
    
            var noResults  = searchResults.Count();
    
            if(searchResults.Any())
            {
                    <p>You searched for <strong><em>@searchString</em></strong>, and found <strong><em>@noResults</em></strong> results</p>
    
                    foreach (var node in searchResults)
                    {
                        IPublishedContent item = Umbraco.Content(node.Fields["id"]);
    
                        <article>
                            <div class="entry-title">
                                <a href="@item.Url"><h2>@item.Name</h2></a>
                            </div>
                            <ul class="date-author inline-list">
                                <li><i class="icon-calendar3"></i>
                                           @(item.HasValue("publicationDate") ? item.GetPropertyValue<DateTime>("publicationDate").ToString("MMM dd, yyyy") : item.CreateDate.ToString("MMM dd, yyyy"))
                                </li> 
    

    etc ...

    It works as expected, with phrases and weighting of full phrases over words, but it's only searching the article title (nodeName). I'm assuming the other properties need to be added into an array, but I have no idea how to create the array and Boost the properties separately (set nodeName higher than the body text.

    The second one below uses the Fluent API, based on a post by Scott Leslie.

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @using Examine;
    @using Examine.SearchCriteria;
    @using Examine.LuceneEngine.SearchCriteria;
    
    @{
        if (!string.IsNullOrEmpty(Request.QueryString["query"]))
        {
            var q = Request.QueryString["query"];
    
            var q_split = q.Split(' ');
    
            var Searcher = ExamineManager.Instance.SearchProviderCollection["ArticleSearcher"];
            var searchCriteria = Searcher.CreateSearchCriteria(Examine.SearchCriteria.BooleanOperation.Or);
            var fieldsToSearch = new[]
            {
             "nodeName", "articleContent", "leadIn"
            };
    
            IBooleanOperation filter = searchCriteria.GroupedOr(fieldsToSearch, q_split.First());        
    
    
        foreach (var term in q_split.Skip(1))
        {
           filter = filter.Or().GroupedOr(fieldsToSearch, term);            
        }   
    
    
        var searchResults = Searcher.Search(filter.Compile()).OrderByDescending(x => x.Score);
        var noResults  = searchResults.Count();
    
            if(searchResults.Any())
            {
    
                    <p>You searched for <strong><em>@q</em></strong>, and found <strong><em>@noResults</em></strong> results</p>
    
    
                    foreach (var node in searchResults)
                    {
                        IPublishedContent item = Umbraco.Content(node.Fields["id"]);
    
                        <article>
                            <div class="entry-title">
                                <a href="@item.Url"><h2>@item.Name</h2></a>
                            </div>
    
                            <ul class="date-author inline-list">
                                <li><i class="icon-calendar3"></i>
                                           @(item.HasValue("publicationDate") ? item.GetPropertyValue<DateTime>("publicationDate").ToString("MMM dd, yyyy") : item.CreateDate.ToString("MMM dd, yyyy"))
                                </li>  etc ... 
    

    This works really well, searching words and phrases. If there is any filtering on the boost score, even at 1, filters out words contained in the body text.

    How would add boosts or fuzzy search to the properties in the array, like you would in the non-split approach?

    like:

    var query = searchCriteria.Field("nodeName", q.Boost(3))
        .Or().Field("articleContent", q.Boost(2))
        .Or().Field("leadIn", q);
    

    Any tips on how to make the approaches above work properly would be much appreciated, thanks!

  • Ismail Mayat 4126 posts 8569 karma points MVP admin c-trib
    1 week ago
    Ismail Mayat
    100

    Afaik with fluentapi and groupedor you cannot add boosts / fuzzy you can only do it with raw query.

    Or you could created your own grouped or by splitting by space and looping then adding to the query each item and adding the boost or fuzzy there.

    Ps in the second code there is no need to order by score by default its ordered by score.

    var searchResults = Searcher.Search(filter.Compile()).OrderByDescending(x => x.Score);
    

    You can lose the order by.

    Regards

    Ismail

  • Shawn Calvert 5 posts 94 karma points
    1 week ago
    Shawn Calvert
    0

    Thank you Ismail! I'll try to work it out, and post if it's successful. Btw, your posts throughout the forum have been super helpful!

Please Sign in or register to post replies

Write your reply to:

Draft