Adding Items to a Custom Sitecore Seach Index using SiteCron

old-books

Over the years working with Sitecore I’ve had to create custom indexes and add items to them for most clients I’ve worked for. I’ve generally written a Search Crawler and Search Indexer to handle this but it’s always seemed like a lot of code to manage just to add a few items to an index and temperamental to control the indexing frequency accurately. I’ve also had many issues with Indexes being out of Sync in the past due to Sitecore Events not firing on CD instances etc.

I’ve tried various approaches to simplifying this in the past but unfortunately never got this working. However this came up again on a recent project and I was successful this time – so decided I’d share my approach and code.
Note in this example I’m using Solr but in Theory this same code should work with Azure Search also.

In simple terms the approach is to:

1) Create a Custom Index – to store my content (in this case Blogs)
2) Create a Search Indexing Service – which will retrieve the Items and add them to the Custom index
3) Create an SiteCron Indexing Job – which will call my Indexing Service to Index the Items on a regular basis
4) Create a Search Results Page – which will display the search results from the Index

Benefits of this approach

  • Less Code to write and manage
  • Can control how often the indexing runs very accurately (using SiteCron) and this persists across App Service / IIS Restarts.
  • Easy to test and maintain

1) Creating a Custom Solr Index

I’m not going to go into this process too much as it’s documented well elsewhere but essentially you need to copy on of the out of the box solr folders, rename it and also update the core.properties file. For this example I’ve created and index called sc93_blogs_index:

custom-index-folder

Configuration

You will also need to add 2 configuration files for the custom Index like so to define the index name, strategy (of manual) and configure the fields to include. Amend these as required for your use-case:

Index Config:
Index Fields Config:

 

2) Search Indexing Service

The next step is to create our Search Indexing Service. This will get the blog items and add them to the index. This could easily be pulling Info from an datatabase, API or File instead if needed.  I’ve called mine BlogPostSearchService:

 public class BlogPostSearchService : ISearchService
 {
  ...
 }

I also added an interface with  two methods:

public interface ISearchService
{
   int IndexContent();

   BlogPostSearchResultsModel GetResults(BlogPostSearchResultsModel blogPostSearchResultsModel, string searchTerm, int resultsPerPage, int currentPage);

}

Index Content Method

The IndexContent() Method is like so. Note this code is not optimal if you have more than a few hundred items within a folder, you may wish to re-structure your items differently:
 

Get Content Method

The GetContent() Method is as follows:

Supporting Models / Classes

There are various supporting models and classes used in the above code. Below are the key ones.

BlogPostSearchResult

My Blog Posts just have two additional properties so this is pretty simple:
public class BlogPostSearchResult: SearchResultItem
{
    [DataMember]
    [IndexField("Title")]
    public string Title { get; internal set; }

    [DataMember]
    [IndexField("Description")]
    public string Description { get; internal set; }
}

BlogPostSearchResultsModel

This Model is used to hold my search results and some other properties about the search results for use in the View:

public class BlogPostSearchResultsModel
{
    public string SearchTerm { get; set; }
    public IPagedList<BlogPostSearchResult> SearchResults { get; set; }
    public int TotalNumberOfResults { get; set; }
    public int NoOfResults { get; set; }
    public int Page { get; set; }
}

Settings

You will notice there are some settings used in the code such as for the Blog Post Items Path. Add a Sitecore patch file for these and configure them as needed.

Paged List

I’m using an Nuget Package for PagedList, this is a good one if you want to use one too: https://github.com/dncuug/X.PagedList

3) SiteCron Indexing  Job

The next step is to create our SiteCron Job which will be responsible for indexing the content. This calls the IndexContent() method on the service. Obviously this needs to match your SiteCron Job name above.
See my post here about logging to the last run log etc if you’d like to do that too.

  This is then setup in SiteCron to run like so, schedule it to run as needed: sitecron-job 

4) Search Results Page

The last step is to display the Search Results. Create a page in Sitecore using whatever template you use. Then Create an Controller Rendering and View in Sitecore, reference the Controller below and add the rendering to the page.

Controller

The Controller looks like so:

View

The View, this is a simplified version:

The Result

So once you’ve done all the above you should end up with something like the following:

search-results-page-blogs

 

Hopefully this helps someone else who need to implement a custom search and illustrates an alternative approach that could work for them.

Published by

Adam Seabridge

I am a Freelance Sitecore Developer and 7x Sitecore Technology MVP (2024 - 2018). I have been working with Sitecore since 2013. You can reach me on twitter @billyjava or comment below if you have any questions or feedback.

Leave a Reply

Your email address will not be published. Required fields are marked *