Solr index – Changing existing Solr index configuration to point to a new collection

We moved our Sitecore implementation to Solr 5.2.1 based on the issues we had faced with Lucene as described in my blog Lucene vs Solr – benefits with Solr.  After few months in the implementation we realized we need to come-up with a better naming convention to maintain & manage large number Solr collections – hence decided to change the Solr collection names.  For the new Search index configuration things were fine, and we were able to index them fine. But for existing Search Indexes after pointing them to new Solr collection – we were unable to index them and were getting below exception,

Exception Stack Trace –
Job started: Index_Update_IndexName=sitecore_master_index_brand|#Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type ISolrOperations`1, key "Prod_Brand_Master_sec" ---> Castle.MicroKernel.ComponentNotFoundException: Requested component named 'Prod_Brand_Master_sec' was not found in the container. Did you forget to register it?
There are 45 other components supporting requested service 'SolrNet.ISolrOperations`1[[System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. Were you looking for any of them?
   at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(String key, Type service, IDictionary arguments, IReleasePolicy policy)
   at Castle.MicroKernel.DefaultKernel.Resolve(String key, Type service, IDictionary arguments)
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key)
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key)
   at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService](String key)
   at Sitecore.Support.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex.Rebuild(Boolean resetIndex, Boolean optimizeOnComplete)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Jobs.Job.ThreadEntry(Object state)

We were using SwitchOnRebuild – so that rebuilding does not affect the search index that is currently used and also providing high availability to the sites / applications. The typical configuration looks like this,

<index id="sitecore_master_index_brand" type="Sitecore.ContentSearch.SolrProvider.SwitchOnRebuildSolrSearchIndex,Sitecore.ContentSearch.SolrSearchProvider">
	<param desc="name">$(id)</param>
        <param patch:after="*[@desc='name']" desc="mainalias">ProdBrandMasterMain</param>
        <param patch:after="*[@desc='mainalias']" desc="rebuildalias">ProdBrandMasterRebuild</param>
        <param patch:after="*[@desc='rebuildalias']" desc="collection">Prod_Brand_Master</param>
	<param patch:after="*[@desc='collection']" desc="rebuildcollection">Prod_Brand_Master_sec</param>

	<!-- This initializes index property store. Id has to be set to the index id -->
        <param desc="propertyStore" ref="contentSearch/databasePropertyStore" param1="$(id)" />
        <configuration ref="contentSearch/indexConfigurations/BrandComContentSolrIndexConfiguration" />

	<strategies hint="list:AddStrategy">
        <!-- NOTE: order of these is controls the execution order -->
            <strategy ref="contentSearch/indexUpdateStrategies/intervalAsyncMaster" />
        </strategies>
        <locations hint="list:AddCrawler">
             <crawler type="Sitecore.Support.ContentSearch.SitecoreItemCrawler, Sitecore.Support.107856">
             <Database>master</Database>
             <Root>/sitecore/Content/Brand</Root>
             </crawler>
        </locations>
</index>

This logically means,

Sitecore Index Solr Alias Solr Collection
sitecore_master_index_brand mainalias – ProdBrandMasterMain Prod_Brand_Master
rebuildalias – ProdBrandMasterRebuild Prod_Brand_Master_sec

At any point of time sitecore_master_index_brand will using either collection Prod_Brand_Master or Prod_Brand_Master_sec or this gets switched every time when full rebuild is done.

Now comes the next question – where does the Sitecore maintains the active collection and rebuild collection, so that it alternatively switches between them.  The answer is – this is maintained in Core Database Properties table through keys  Active_Collection, Rebuild_Collection. It looks like this in Core DB, with the value representing the Solr collection name.

ID Key Value
C4205D64-D82E-4EA8-B90A-52A5104A37D6 SITECORE_MASTER_INDEX_BRAND_CM1_SOLR_ACTIVE_COLLECTION Prod_Brand_Master_sec
139148CF-53DD-49A9-ADDC-8A5999201949 SITECORE_MASTER_INDEX_BRAND_CM1_SOLR_REBUILD_COLLECTION Prod_Brand_Master

Coming back to the exception we received while re-indexing changing the Solr collection name in the index configuration – the issue was because of this mapping that is maintained in the Properties table.  The mappings here were pointing to old collection names.  The instructions from Sitecore support to handle this scenario is,

  • Clean-up these entries in Core DB Properties table
  • Recycle the application pool of your Sitecore instance

Once done, you will now be able to successfully re-index – as now in this case Properties table will get populated with mapping pointed to changed collection names.

Advertisements

2 thoughts on “Solr index – Changing existing Solr index configuration to point to a new collection

  1. Good one Deepak , i have a question here ,you are asking to clean up properties table here ,is this manual activity or is sitecore providing any feature to cleanup?

    If it is manual , what if we dont have access to database.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s