Site search is one of the main functionalities of any sitecore site, and building this functionality considering best practices and performance is very important.
This document will cover sitecore search implementation guideline with performance improvement using solr.
Implementing full content search including content of data Source items and global content items
Usually most of the pages of sitecore sites displays content of the page items as well as content of sub items/content items which are used as datasouce items on the page.
This is ideal approach to build the pages of site but when it comes to developing the site search where you want all content of the page to be searchable including data sources items it becomes difficult
Also read: Sitecore 9.3 Custom Link Provider
If we include the datasouce items itself in to the search result, it will be very difficult to manage its link as pages in search results should be clickable and should redirect user to the right page.
Also there will be duplicate results as single page can have multiple data source items associated with it.
To handle this scenario, we have used solr computed fields where we are adding content of all datasouce items in to the computed field on the main page items where data source items are used.
Whenever item is indexed it will trigger computed fields code and will push the content of DS items in to it.
By default, _Content field of solr indexes contains all the text fields content on the items which uses same logic which we wrote for the computed field to gather DS items content.
Sitecore indexes can have more than one value for same index field that’s why we can add custom computed fields content to _content field.
Now the _content index field stores two values one is default system value, and computed value both values will be searchable when you query it.
1.Create custom Indexes
Search performance is depending on the size of the data in the search index. More the data more is index size and it will take more time searching and indexing the data while building indexes.
If you use site core’s default indexes (sitecore_master_index or sitecore_web_index) it will impact the search performance as it indexes all sitecores content with all fields
Best way is to create a custom index with only required template and fields.
2.Add only required content in custom Index
By following below below points we can reduce size of indexes and improve the indexing build time.
- configure your index crawlers to include only the portion that it needs to crawl and index
- Try to avoid <virtualFields>
- Reduce number of computed fields
- Set <indexAllFields> to false and include only required field
- Include only the templates you need using <include> element
If your search functionality has category filtration, then you can facet instaed of using normal queries to the the aggregate count of the result based on the categories.
Lucene and SOLR both provides support for Facets using Content Search API.See below snippet
FacetResults searchfacet = queryable.Where(predicate).FacetOn(x => x[“custom_search_tags_pages_sm”], 1).GetFacets();
FacetOn can be on multiple fields like below
().Where(predicate).FacetOn(x => x[“Propery1Name”],
1). FacetOn(x => x[“Propery2Name”], 1).GetFacets();
4. Use Custom model instead of SearchResultItem.
Sitecore SearchResultItem maps a lot of properties which we don’t need during our search. That’s why it’s better for the performance to create custom SearchResultItem which contains only the properties that you actually need during searching.
5.Use index to get all data (search results properties) instead of querying database by getting only item id from index
We normally load the itemId form the solr indexes and then use db.GetItem(id.ItemId) to get the item form database for fetching all search results properties.
So if you are displaying 15 results on single page, database calls will be 15 times as we have to bind all 15 results properties to the model.
So instead of doing db calls we can load all the properties from indexes and bind it to model, in that way can we are avoiding DB call and improving performance.
If we follow above steps, search performance can improve by 3 to 4 seconds depending on the complexity of your code.
Also read: Personalization Buzzwords Explained
Updating Page Item’s Index On Publishing of data source Items/Related Sub Items
In above Approach we are using Solr computed field to stored content of data source items on the main page items computed field.
So Whenever the content of datasource items changes main page items indexes should get updated to keep the data up to date in computed field.
As per the sitecores IndexUpdateStratergies, Index of item gets updated whenever we publish/Save the Item.
But It will not update index documents that are using changed item in computed fields.
So to resolve this issue we can add some events like item:saved/item:publish:end
to update the index of referenced item
This is asynchronous method to updated the index which is better than synchronous way
(index,uniqueId) will update index documents
for items passed in parameters. So on publish end we will get all references of the published item and updated its index node using this method.
Below is the code for the same.
public void UpdateIndex (ISearchIndex index, ICollection<Item> items)
foreach (Item item in items)
// var versions = item.Versions.GetLatestVersion();
var uniqueId = new SitecoreItemUniqueId(item.Uri);
Log.Info(“Update” + “uniqID”+ uniqueId, this)
Sitecore solr search implementation with performance improvement will be completed by following the above steps.