ASP.NET, Enterprise Search

The complete guide to getting started with Solr in Sitecore

Solr is a highly reliable search platform that powers the search and navigation features of many of the world’s largest internet sites. It provides distributed indexing, replication with load-balanced querying, automated failover and recovery, centralized configuration and more.

Sitecore on the other hand, is a leading digital experience software used by organizations globally to create seamless, personalized digital experiences. Sitecore is a web content and experience management platform that includes standard CMS, commerce and digital marketing tools in an integrated environment that runs on .NET and the Microsoft web stack (Windows, IIS, SQL Server, etc.)

When we combine Sitecore’s power with Solr search capabilities we get the best of both worlds. Using Solr with Sitecore requires a few installation and configuration steps. In some cases, these steps can be automated using tools like SIF (the Sitecore Installation Framework) while in others they must be manually implemented. The following steps demonstrate how you can install and configure Solr for use with Sitecore:

Solr installation

The first step to using Solr with Sitecore is installing it. These instructions are for setting Solr up as a Windows service on a single machine for use alongside Sitecore 9.1. This is typically the configuration used by developers for development purposes or for basic situations like a demo server. Different configurations and different versions of Sitecore may require different Solr topologies and different setup steps. You will want to perform these steps prior to installing Sitecore itself as the installation scripts provided by Sitecore expect Solr to be running before they are run.

Solr logging

Solr logs are a key way to know what’s happening in the system. By default, Solr log messages will be written to server/logs/solr.log. If problems arise, the Solr logs help understand the causes and are invaluable for troubleshooting. The Solr Admin web interface has a section for logging which allow you to set the log level for many different categories of logging. If individual categories don’t have their own logging level, then they will inherit the logging level of their parent. This makes it easy to adjust and maintain logging levels by setting the logging level of a common parent.

Indexing Sitecore content in Solr

First, let’s understand how indexing works and ensure that Sitecore data is appearing in our index.

1. First ensure the Connection String for Solr is correct in your connection strings config (typically “connectionstrings.config”).

2. Then create a Data Template in Sitecore

3. Create a View Rendering to display the content that will be indexed using your standard Sitecore development methods.

4. Use the template you created to create a few content items and add some data.

5. Next make sure the content is indexed by using the Sitecore Control Panel’s Index manager. If you are using any existing indexes, then rebuild it.

6. After indexing, check that the data is present in the index. This is done by going into the Solr interface (at https://localhost:8986/solr). Choose the core representing the Sitecore database you want to view content in from the dropdown, then enter the parameters seen below.

You should now see your content in the Solr index.

Creating a basic Sitecore search page with Solr

1. After indexing is done, Open a new solution in Visual Studio.
2. Create a Custom Route for Sitecore URL under App_Start folder.

Create a custom processor for the initialize pipeline and define custom route in the Process method like the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.UI.WebControls;
using Sitecore.Pipelines;

namespace SitecoreSolrIndexing.CustomRoutes
    public class RegisterCustomRoute
        public virtual void Process(PipelineArgs args)
        public static void Register()
            RouteTable.Routes.MapRoute("CustomRoute", "api/testing/{controller}/{action}");

Add this processor to the initialize pipeline right before the Sitecore InitializeRoutes processor. You can do this with the help of the configuration patch file in the following way:

Config File Code:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="">
        <processor type="SitecoreSolrIndexing.CustomRoutes.RegisterCustomRoute, SitecoreSolrIndexing" patch:before="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']"/>

3. Create the Sitecore Search View

Create a Search text box and button on the HTML page where the user will be able to type and search for the record from Solr. Write script to create the AJAX call to call server-side controller action method on click of Search button created in above step. Below is the full code for HTML and script.

    ViewBag.Title = "Search Item";

<h2>Search Item</h2>

<div class="form-example">
    <label for="name">Search Item </label>
    <input type="text" name="name" id="searchText" required>
<br />
<br />
<div class="form-example">
        <button class="favorite styled" type="button" id="searchButton" >
<div id="resultsItem"></div>

    $(document).ready(function () {
        $("#searchButton").click(function (e) {
                type: "GET",
                datatype: "JSON",
                url: "@Url.Action("DoSearch", "Index")",
                contentType: "application/json",
                data: {
                    searchItem: $("#searchText").val()                          
                success: function (result) {                    
			$(‘.resultsItem').text(result.Results[0].Title + "; " + result.Results[1].Title + "; " + result.Results[2].Title);                
                error: function (result) {

4. Implement the Controller Code

Here, we are creating a “DoSearch” method for the search results while “GetSearchPredicate” method for appending the predicate for the search query and we are returning the JSON value.

Using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Linq;
using Sitecore.ContentSearch.Linq.Utilities;
using SitecoreSolrIndexing.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace SitecoreSolrIndexing.Controllers
    public class IndexController : Controller
        public ActionResult DoSearch(string searchItem)
            var myResults = new SearchResults
                Results = new List<SearchResult>()

            var searchIndex = ContentSearchManager.GetIndex("sitecore_web_index"); // Get the search index
            var searchPredicate = GetSearchPredicate(searchItem); // Build the search predicate

            using (var searchContext = searchIndex.CreateSearchContext()) // Get a context of the search index
                var searchResults = searchContext.GetQueryable<SearchModel>().Where(searchPredicate); // Search the index for items which match the predicate

                // This will get all of the results, which is not recommended
                var fullResults = searchResults.GetResults();

                foreach (var hit in fullResults.Hits)
                    myResults.Results.Add(new SearchResult
                        Description = hit.Document.Description,
                        Title = hit.Document.ItemName,
                        Heading = hit.Document.Heading,
                        SubHeading = hit.Document.SubHeading
                return ResultJson(myResults);

        public JsonResult ResultJson(object data)
            return new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = data };
        public static Expression<Func<SearchModel, bool>> GetSearchPredicate(string searchTerm)
            var predicate = PredicateBuilder.True<SearchModel>();
            // Search the whole phrase – CONTAINS
            predicate = predicate.Or(x => x.Heading.Contains(searchTerm));            predicate = predicate.Or(x => x.SubHeading.Contains(searchTerm));
            predicate = predicate.Or(x => x.Description.Contains(searchTerm));
            predicate = predicate.Or(x => x.Title.Contains(searchTerm)); 

            return predicate;


5. Implement The Model Code

Solr creates the property on the Solr server for all the default and custom fields. To use those fields in code, map them in a Class given below:

using Sitecore.ContentSearch;
using Sitecore.ContentSearch.SearchTypes;
using System.Collections.Generic;

namespace SitecoreSolrIndexing.Models
    public class SearchModel : SearchResultItem
        public virtual string ItemName { get; set; }

        public virtual string Heading { get; set; }

        public virtual string SubHeading { get; set; }

        public virtual string Description { get; set; 
        public virtual string Title { get; set; }


    public class SearchResult
        public string Title { get; set; }
        public string Heading { get; set; }
        public string SubHeading { get; set; }
        public string Description { get; set; }

    /// <summary>
    /// Custom search result model for binding to front end
    /// </summary>
    public class SearchResults
        public List<SearchResult> Results { get; set; }

6. See your results

Now that all the parts are all in place it’s time to see the fruits of our labor.

First build and publish whole solution. Then perform a search. If you get search results, everything is working.

About The Author