Minimizing Schema Changes to Sitecore Indexes

Minimizing Schema Changes to Sitecore Indexes

I ran into a delimma recently with making some changes to the schema.xml that was purposed for a site in a multi-site Sitecore instance. With Solr, I was attempting to implement EdgeNGram for searching and realized adding a field mapping for a new field type in the index impacted all my indexes for the other sites.

Implementing EdgeNGram was fairly straight forward as Ehab ElGindy's blog post
was very helpful. However, I didn't want to introduce this to all the sites. So I needed some way to limit scope of my configuration change to only my site.

Here is an example of my patch:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
      <contentSearch>
          <indexConfiguration>
              <defaultSolrIndexConfiguration  type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
                  <fieldMap type="Sitecore.ContentSearch.SolrProvider.SolrFieldMap, Sitecore.ContentSearch.SolrProvider">
                      <typeMatches hint="raw:AddTypeMatch">
                          <typeMatch typeName="autoComplete" type="System.String" fieldNameFormat="{0}_ac" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider" />
                      </typeMatches>
                  </fieldMap>
              </defaultSolrIndexConfiguration
          </indexConfiguration>
      </contentSearch>
  </sitecore>
</configuration>

The field map matches to a new field type that was introduced in the site's schema.xml in Solr. However, I found that it would break all the other indexes since this field map was patched on the default Solr configuration.

To get around this, I created a duplicate of Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config and titled it after the site for example Sitecore.ContentSearch.Solr.MySiteIndexConfiguration.config.

There are a couple of updates to the file that need to happen so we are not duplicating settings and so we have our own configuration for MySite.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <contentSearch>
      <!-- Configuration sections for indexes -->
      <indexConfigurations>

        <!-- If an index has no configuration specified, it will use the configuration below. The configuration is not merged if the index also has
             configuration, it is either this configuration or the index configuration. -->
        <mySiteSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
          ...
        </mySiteSolrIndexConfiguration>
      </indexConfiguration>
    </contentSearch>
  </sitecore>
</configuration>

Basically, we will change defaultSolrIndexConfiguration node to mySiteSolrConfiguration and leave all the children in between them.

At the end of the file, we need to delete the settings and pipeline node as this will not matter and will only duplicate settings and pipelines.

We can also check the Sitecore logs to see if it is reporting any duplicate configuration when it starts up.

Next, we just need to update our index definition for MySite to reference the configuration and update our patch file for adding the field mapping.

          <index id="sitecore_mysite_web_index" type="Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider">
            <param desc="name">$(id)</param>
            <param desc="core">$(id)</param>
            <param desc="propertyStore" ref="contentSearch/indexConfigurations/databasePropertyStore" param1="$(id)" />
            <configuration ref="contentSearch/indexConfigurations/mySiteSolrIndexConfiguration" />
            <strategies hint="list:AddStrategy">
              <strategy ref="contentSearch/indexConfigurations/indexUpdateStrategies/onPublishEndAsync" />
            </strategies>
            <locations hint="list:AddCrawler">
              <crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
                <Database>web</Database>
                <Root>/sitecore/content/MySite</Root>
              </crawler>
            </locations>
            <enableItemLanguageFallback>false</enableItemLanguageFallback>
            <enableFieldLanguageFallback>false</enableFieldLanguageFallback>
          </index>

Notice here we updated <configuration ref="contentSearch/indexConfigurations/mySiteSolrIndexConfiguration" /> to reference our new configuration and not the default.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
      <contentSearch>
          <indexConfiguration>
              <mySiteSolrIndexConfiguration  type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
                  <fieldMap type="Sitecore.ContentSearch.SolrProvider.SolrFieldMap, Sitecore.ContentSearch.SolrProvider">
                      <typeMatches hint="raw:AddTypeMatch">
                          <typeMatch typeName="autoComplete" type="System.String" fieldNameFormat="{0}_ac" settingType="Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider" />
                      </typeMatches>
                  </fieldMap>
              </mySiteSolrIndexConfiguration
          </indexConfiguration>
      </contentSearch>
  </sitecore>
</configuration>

Here we updated the defaultSolrIndexConfiguration node in our patch file to mySiteSolrIndexConfiguration.

I found this to be a quick and easy way around limiting the change to indexes in Sitecore. The last thing I could have done was moved my field map to mySiteSolrIndexConfiguration instead of having an extra configuration file to patch the Sitecore config.