Providing smart search on MVC sites

If you want to provide smart search on your MVC sites, you need to configure automatic Web farm mode in Kentico and install the Kentico.Search integration package in your MVC application. With the Web farm service enabled and the related web farm servers showing Healthy status, search indexes on MVC applications are updated automatically.

This means that no additional configuration is necessary. If you want to process the tasks in a regular interval (by a scheduler), you need to use the Scheduler Windows service since the standard way of scheduling tasks is not available in MVC applications.

Displaying search results

The Kentico.Search integration package provides access to Kentico smart search. You can use the provided functionality to perform a search in your controllers and return search results.

Example

The following example does not make use of paging when displaying search results. You can see an implementation of search with the use of paging on our MVC Demo site (GitHub).

  1. Install the Kentico.Search integration package in your MVC application.
  2. Create a new model for working with search queries and search results.

    using Kentico.Search;
    
    namespace MVCSite.Models.Search
    { 
        public class SearchResultsModel
        {
            public string Query
            {
                get;
                set;
            }
    
    		public IEnumerable<SearchResultItem> Items
            {
                get;
                set;
            }
    
    		public int ItemCount
            {
                get;
                set;
            }
        }
    }
  3. Create a controller and a controller action for displaying the results.
    The Kentico.Search.SearchService.Search() method returns items only for a specific search results page. In the example below, the results are returned for the first page (page variable set to 0).

    using MVCSite.Models.Search;
    
    ...
    
    public class SearchController : Controller
    {   
    	// Adds the smart search indexes that will be used when performing a search 
        public static readonly string[] searchIndexes = new string[] { "MVCSite.Index" };
        public const string SITE_NAME = "MVCSite";
    	private const int PAGE_SIZE = 10;
    
    	private readonly SearchService mService = new SearchService(searchIndexes, "en-US", SITE_NAME, false);
    
        // GET: Search
        [ValidateInput(false)]
        public ActionResult Index(string searchText)
        {
            int numberOfResults;
            var model = new SearchResultsModel()
            {
                Items = mService.Search(
                    searchText,
                    page: 0,
                    pageSize: PAGE_SIZE,
                    numberOfResults: out numberOfResults),
                Query = searchText,
    			ItemCount = numberOfResults
            };
            return View(model);
        }
    }
  4. Provide a search field in one of your views. For example:

    @using (Html.BeginForm("Index", "Search", FormMethod.Get, new { @Id = "searchForm", @Class = "searchBox" }))
    {
        <input type="text" name="searchtext" placeholder="Search..." maxlength="1000">
        <input type="submit" value="Search"> 
    }
  5. Provide a view that displays search results.
    In MVC applications, you generate the URLs for the content available on your site. You'll need to match search results to the particular items that you want displayed. The following example uses a GetUrl method which calls a controller action depending on the page type of each page returned by the search.

    @using MVCSite.Models.Search;
    @model SearchResultsModel
    
    @if (Model.Items == null)
    {
        if (!String.IsNullOrWhiteSpace(Model.Query))
        {
            <h2>No results found for @Model.Query</h2>
        }
    }
    else
    {
    	<h2>Found @Model.ItemCount results.</h2>
        foreach (var item in Model.Items)
        {
            <a href="@GetUrl(item.PageTypeCodeName, item.NodeId)">@item.Title</a>
        }   
    }
    
    @helper GetUrl(string pageTypeCodeName, int nodeId)
    {
    	switch (pageTypeCodeName)
        {
            case "MVCSite.Article":
    	        @Url.Action("Show", "Articles", new { id = nodeId })
                break;
            default:
                throw new NotImplementedException("Unknown PageType: " + pageTypeCodeName);
        }
    }