contact@skillcore.net

Sitecore and Solr - custom field reader and indexing

Posted 30 August 2014 by Marek Musielak

sitecore and solr - custom field reader and indexing

Nowadays Solr-powered Sitecore solutions are more and more popular and easier to setup. Stephen Pope and Sitecore team are doing great job there. Sitecore 7.2 provides a lot of support for Solr out of the box but there are still some scenarios when you need to extend Sitecore to fit your needs. Just recently I needed to implement a custom way of indexing and retrieving item fields for Solr.

In our project we had a template containing Multi-Line Text field called My Ideas. In this field users were supposed to enter their ideas, each in separate line. Sample content of the field looked like this:

sitecore multi-line text field

We used the content of this field to populate an unordered list with a single <li> tag for each line. We wanted to get the lines directly from the Solr as a list of strings without a need to parse the string later. By default when Sitecore Multi-Line Text fields are indexed by Solr, they are stored as tokenized text values so my field in Solr was:

sitecore and solr - indexing text field

You may notice that the Sitecore field name My Ideas is translated into Solr key my_ideas_t - lowercase, spaces replaced with underscores and suffix _t added as this is a text entry. If we want Solr to treat a field as stringCollection field we need to update in the App_Config\Include\Sitecore.ContentSearch.Solr.Indexes.config file <fieldNames> entry with our field:

<fieldMap type="Sitecore.ContentSearch.SolrProvider.SolrFieldMap, 
                                   Sitecore.ContentSearch.SolrProvider">
  <fieldNames hint="raw:AddFieldByFieldName">
	<fieldType fieldName="my_ideas" returnType="stringCollection" />
    ...
  </fieldNames>
</fieldMap>

Now when I re-indexed the item, the key for my field in Solr was changed to my_ideas_sm. Solr treats this field like a collection of strings but it still doesn't know how to parse the text, that's why my field looks like this now:

sitecore solr - string collection field

The next step was to create a custom field reader for Multi-Line Text field and register it in App_Config\Include\Sitecore.ContentSearch.Solr.Indexes.config file:

namespace SolrSitecore.Custom.FieldReader
{
    public class MultiLineListFieldReader : FieldReader
    {
        public override object GetFieldValue(IIndexableDataField indexableField)
        {
            Field field = (SitecoreItemDataField)indexableField;
            return (field.Value ?? String.Empty).Split(new[] { "\r\n" },
                StringSplitOptions.RemoveEmptyEntries).ToList();
        }
    }
}
<fieldReaders type="Sitecore.ContentSearch.FieldReaders.FieldReaderMap, Sitecore.ContentSearch">
  <mapFieldByName hint="raw:AddFieldReaderByFieldName">
    <fieldReader fieldName="My Ideas"
    fieldReaderType="SolrSitecore.Custom.FieldReader.MultiLineListFieldReader, SolrSitecore" />
  </mapFieldByName>
  <mapFieldByTypeName hint="raw:AddFieldReaderByFieldTypeName">
  ...
  </mapFieldByTypeName>
</fieldReaders>

Now finally the field was indexed as I wanted and I was able to use it in my SearchResultItem class:

sitecore solr - string collection field

namespace SolrSitecore.Custom.Indexing
{
    public class MySearchResultItem : SearchResultItem
    {
        [IndexField("My Ideas")]
        public List<string> MyIdeas { get; set; }
    }
}

That 3 easy steps allow you to create and use custom field readers and indexing options for Sitecore Solr solutions. Thanks for reading and if you liked this blog post click here to tweet about it. You may also be interested in my other blog post about using SwitchOnRebuildSolrSearchIndex Solr provider for Sitecore.