Sorting the Search Results

Sorting the Search Results

Posted on February 14, 2013 0 Comments

The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.

Edit: The below blog post is supported on versions till 7.2. In case using Sitefinity 7.3+ you can refer to the documentation article here.

Scenario

I want to be be able to give certain search results higher precedence than others in the full list of results. Think of it as putting the sponsored / featured search results on top of the others. 
Here is my particular scenario: I have lots of news items. I want to:

1. Order the news by a custom field named Featured in the news list

2. Order the search results so that the featured news are always on top.

The first requirement is very easy to achieve - edit the News widget and go to Advanced mode then ControlDefinition > Views > NewsFrontendList and find the SortExpression property. By default it's set to PublicationDate DESC which puts the newest items on top. Just change the value to Featured DESC and the news list will be sorted / ordered by the Featured custom field.
Figure: sorting the news items by custom field

And here is how the news list looks like (note the featured items are on top):


Figure: the news list is sorted by a custom field

The second requirement is not that easy, because the SearchResults widget does not have a SortExpression property. As a result, the search results are not ordered:


Figure: the search results are not sorted by default

Fortunately, the Search service has a search method that can accept an orderBy parameter and we are going to take advantage of it:

IResultSet Search(string catalogueName, string query, string[] highlightedFields, int skip, int take, string[] orderBy, params object[] additionalParams);

To do that, we are going to extend the SearchResults widget by adding a SortExpression property which will control the order of the search results and override a few methods. 

public class CustomSearchResults : SearchResults
{      
        public string SortExpression { get; set; }
  
...
}

When you register the widget in the toolbox (best done by Sitefinity Thunder) the SortExpression property will automatically appear in the control designer of our CustomSearchResults widget (in Edit mode) and the content authors will be able to set it to the value they want.  

Now to the real work - we need to override a few methods and interfaces of the SearchResults class (it's not that scary as it sounds), but the most important is the Search method override. The complete code is below:

public class CustomSearchResults : SearchResults
{       
    public string SortExpression { get; set; }
 
    protected override SearchResults.ISearcher GetSearcher()
    {
            return new MyOrderedSearcher(this);
    }
 
    private class MyOrderedSearcher : MySearcher
    {
        public MyOrderedSearcher(CustomSearchResults control)
            : base(control)
        {
        }
 
        public override IEnumerable<IDocument> Search(string query, string catalogue, int skip, int take, out int hitCount)
        {
            CustomSearchResults searchResult = this.control;
            ISearchService searchService = searchResult.GetSearchService();
            string str = searchResult.BuildSearchQuery(query, searchService);
 
            var sortExpression = string.IsNullOrEmpty(searchResult.SortExpression) ? null : new[] { searchResult.SortExpression };
            IResultSet resultSets = searchService.Search(catalogue,                       str,                                     searchResult.HighlightedFields,         skip,                                   take,                                 sortExpression,                         new object[0]);
            hitCount = resultSets.HitCount;
            return resultSets.SetContentLinks();
        }
    }
 
    private abstract class MySearcher : CustomSearchResults.ISearcher
    {
        protected CustomSearchResults control;
 
        public MySearcher(CustomSearchResults control)           
        {
            this.control = control;
        }
 
        public abstract IEnumerable<IDocument> Search(string query, string catalogue, int skip, int take, out int hitCount);
    }       
}

and the necessary using statements:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Sitefinity;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.DynamicModules;
using Telerik.Sitefinity.Data.Linq.Dynamic;
using Telerik.Sitefinity.DynamicModules.Model;
using Telerik.Sitefinity.GenericContent.Model;
using Telerik.Sitefinity.Utilities.TypeConverters;
using Telerik.Sitefinity.Security;
using Telerik.Sitefinity.Lifecycle;
using Telerik.Sitefinity.Services.Search.Web.UI.Public;
using Telerik.Sitefinity.Services.Search.Data;
using System.Collections;
using Telerik.Sitefinity.Services.Search;

What this code does is, if the SortExpression property is empty then we pass the null value to the Search method (no sorting), otherwise we pass the value of the property (which is our sort expression). Here is how it looks like in the backend:


Figure: the custom search results widget with SortExpression property

Just a couple of administrative tasks are left to be done:

0. Register the widget in the toolbox so that you can drag and drop it on a page.
1. Edit your Search Index catalogue and add the custom field into the "Additional fields for indexing" so that the Lucene search provider knows about your field:


Figure: adding the custom field to the search catalogue

2. Reindex the search catalogue.

And you are ready to go. Let's see it in action:


Figure: the sorted search results

This approach can be applied not only to built-in content types (news, blogs, etc.), but also to any custom content types created by the Module Builder.

Here is the full code of the custom search results widget.

 

progress-logo

The Progress Team

View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments

Comments are disabled in preview mode.
Topics

Sitefinity Training and Certification Now Available.

Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.

Learn More
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation