Providing smart search on MVC sites

Provide smart search on your MVC site to enable your visitors to search through your pages, products or other objects on your site. Smart search is an index-based search engine, which allows users to search through the content of websites and various types of data within the system. The smart search uses indexes to store information about the website content. See Setting up search on your website to learn more about smart search.

To provide smart search on your MVC site:

  1. Configure automatic Web farm mode in Kentico.
  2. Enable smart search indexing.
  3. Create search indexes. Assign the indexes to your site and define their exact content.

    With the Web farm service enabled and the related web farm servers showing the Healthy status, search indexes on MVC applications are updated automatically.

    If you want to process the tasks in a regular interval (e.g. by a scheduler), you need to use the Scheduler Windows service since the standard way of scheduling tasks is not available in MVC applications.

  4. Install the Kentico.Search integration package to your MVC application.
  5. Initialize the SearchService from the integration package with the indexes you want to search through.

Use the Search method that executes the search and returns a set of results of the SearchResult class.

            ISearchService searchService = new SearchService();
            
            SearchResult searchResult = searchService.Search(new SearchOptions(searchText, searchIndexes)
            {
                CultureName = "en-us",
                CombineWithDefaultCulture = true,
                PageSize = PAGE_SIZE
            });
In the search result's Items property, you can find the Fields and Data properties. The Fields property contains fields available for all full-text search result items (such as the title or image). The Data property is of an abstract BaseInfo class. Its run-time type contains all type specific properties. For example:

  • If the search indexes users, the run-time type of a search result item's Data property is of the UserInfo class.
  • If the search indexes pages, the run-time type of a search result item's Data property is of the TreeNode class. If you generated classes for your page types, the run-time type is of the generated class.
  • If the search indexes pages representing products, the run-time type of a search result item's Data property is of the SKUTreeNode class.

With the Data property, you can access any object-specific property.

Currently, the Kentico.Search integration package supports all types of search indexes except the custom indexes.

Example – Providing search on MVC sites

The following search example uses an index that indexes pages (TreeNode objects) and products (SKUTreeNode objects). The example does not use pagination when displaying search result items.

Tip: To view the full code of a functional example directly in Visual Studio, download the Kentico MVC solution from GitHub and inspect the LearningKit project. You can also run the Learning Kit website after connecting the project to a Kentico database.

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

        public class SearchResultModel
        {
            public string Query { get; set; }
            
            public IEnumerable<SearchResultItemModel> Items { get; set; }
        }
    

  3. Create a new model for the search result item (SearchResultItemModel in the example).

  4. Create a controller with a controller action for displaying the results.

    using System;
    using System.Collections.Generic;
    using System.Web.Mvc;
     
    using CMS.DataEngine;
     
    using Kentico.Search;
    
            // Adds the smart search indexes that will be used when performing a search and sets item count per page
            public static readonly string[] searchIndexes = new string[] { "MVCSite.Index" };
            private const int PAGE_SIZE = 10;
            
            /// <summary>
            /// Constructor.
            /// Initializes the search service that takes care of performing searches. You can use a dependency injection container to initialize the service.
            /// </summary>
            public SearchController()
            {
                searchService = new SearchService();
            }
            
            /// <summary>
            /// Performs a search and displays its result.
            /// </summary>
            /// <param name="searchText">Query for search.</param>
            [ValidateInput(false)]
            public ActionResult SearchIndex(string searchText)
            {
                // Displays the search page without any search results if the query is empty
                if (String.IsNullOrWhiteSpace(searchText))
                {
                    // Creates a model representing empty search results
                    SearchResultModel emptyModel = new SearchResultModel
                    {
                        Items = new List<SearchResultItemModel>(),
                        Query = String.Empty
                    };
                    
                    return View(emptyModel);
                }
                
                // Searches with the smart search through Kentico and gets the search result
                SearchResult searchResult = searchService.Search(new SearchOptions(searchText, searchIndexes)
                {
                    CultureName = "en-us",
                    CombineWithDefaultCulture = true,
                    PageSize = PAGE_SIZE
                });
                
                // Creates a list for search result item models
                List<SearchResultItemModel> itemModels = new List<SearchResultItemModel>();
                
                // Loops through the search result items
                foreach (SearchResultItem<BaseInfo> searchResultItem in searchResult.Items)
                {
                    // Adds data to a view model. You can adjust the logic here to get to the object specific fields
                    itemModels.Add(new SearchResultItemModel(searchResultItem.Fields));
                }
                
                // Creates a model with the search result items
                SearchResultModel model = new SearchResultModel
                {
                    Items = itemModels,
                    Query = searchText
                };
                
                return View(model);
            }
    

  5. Provide a search field in one of your views. For example:

    @using (Html.BeginForm("SearchIndex", "Search", FormMethod.Get))
    {
        <input type="text" name="searchtext" placeholder="Search..." maxlength="1000">
        <input type="submit" value="Search">
    }
    

  6. Provide a view that displays search result items.

    @model SearchResultModel
     
    @if (!Model.Items.Any())
    {
        if (!String.IsNullOrWhiteSpace(Model.Query))
        {
            <h3>No results found for "@Model.Query"</h3>
        }
    }
    else
    {
        <h3>Results for "@Model.Query"</h3>
        foreach (SearchResultItemModel item in Model.Items)
        {
            <div>
                @item.Title
                @item.Date.ToLongDateString()
            </div>
        }
    }
    

Your visitors can now search on your website with the created search field. The system displays the results based on the indexes specified in the MVC application.


Was this page helpful?