Add Custom Fields in SOLR Index on Crawler

While upgrading the project from Sitecore version 8.2 to 10.2 I faced one scenario to convert the Lucene Search configuration to the SOLR.

It’s easier to convert the Lucence configuration to the SOLR if all configurations are defined in the configuration files. You just need to change the type to the Solr Provider and configuration to the defaultSolrIndexConfiguration or if it does not default then define the custom Solr Index configuration.

The problem occurs when the index file is generated at runtime and custom fields are added dynamically either on the pipeline or Search Crawler. In my case in Sitecore 8.2 lucence configuration fields were added in the document at runtime on SitecoreItemCrawler.

Custom Crawler:

<crawler type="project.Website.Indexes.Career.CustomCareerSearchCrawler, project.Website">

Code was written on the custom crawler:

using Lucene.Net.Documents;
public class CustomCareerSearchCrawler : SitecoreItemCrawler
{
public readonly List<ID> _templateIDs = new List<ID>();
public string Templates { get; set; }
public string LanguageName { get; set; }
public override void Initialize(ISearchIndex searchIndex)
{
Assert.IsNotNullOrEmpty(Templates, "TemplateIDs");
var ids = Templates.Split('|');
_templateIDs.Clear();
foreach (var id in ids)
{
_templateIDs.Add(new ID(id));
}
base.Operations = new CustomIndexOperations()
{
TemplateIDs = this._templateIDs,
SearchIndex = searchIndex
};
base.Initialize(searchIndex);
}
}
public class CustomIndexOperations : IIndexOperations
{
public void Add(IIndexable indexable, IProviderUpdateContext context, ProviderIndexConfiguration indexConfiguration)
{
var item = (Item)(indexable as SitecoreIndexableItem);
if (!TemplateIDs.Contains(item.TemplateID))
{
return;
}
var endDate = item.GetDateTime("Valid Application To");
if (endDate.HasValue && endDate.Value < DateTime.Now)
{
Delete(indexable.UniqueId, context);
return;
}
if (item.Versions.Count <= 0)
{
Delete(indexable.UniqueId, context);
return;
}
var document = new Document();
document.Add(new Field("_uniqueid", indexable.UniqueId.Value.ToString(), Field.Store.YES, Field.Index.ANALYZED));
document.Add(new Field("_datasource", indexable.DataSource.ToLowerInvariant(), Field.Store.YES, Field.Index.ANALYZED));
document.Add(new Field("_indexname", SearchIndex.Name.ToLowerInvariant(), Field.Store.YES, Field.Index.ANALYZED));
document.Add(new Field("_content", string.Format("{0}|{1}", item.Name, item.ID.ToString()), Field.Store.YES, Field.Index.ANALYZED));
document.Add(new Field("_langauge", item.Language.Name, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("_id", item.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("_name", item.Name, Field.Store.YES, Field.Index.NOT_ANALYZED));
document.Add(new Field("_title", item["Job Position"], Field.Store.YES, Field.Index.NOT_ANALYZED));
context.AddDocument(document, indexable.Culture != null ? new CultureExecutionContext(indexable.Culture) : null);
}
}

Solution:

To resolve the above issue and find the solution, I have explored Sitecore.ContentSearch DLL and found out it provides the below method in the IProviderUpdateContext interface.

void AddDocument(object itemToAdd, IExecutionContext executionContext);
void AddDocument(object itemToAdd, params IExecutionContext[] executionContexts);
void Delete(IIndexableUniqueId id, params IExecutionContext[] executionContexts);
void Delete(IIndexableId id, params IExecutionContext[] executionContexts);
void UpdateDocument(object itemToUpdate, object criteriaForUpdate, IExecutionContext executionContext);

In Sitecore 10.2 it takes a parameter object as a type of Dictionary. Hence I updated the code as mentioned below:

var document = new Dictionary<string, object>();
document.Add("_uniqueid", indexable.UniqueId.Value.ToString());
document.Add("_datasource", indexable.DataSource.ToLowerInvariant());
document.Add("_indexname", SearchIndex.Name.ToLowerInvariant());
document.Add("_content", string.Format("{0}|{1}", item.Name, item.ID.ToString()));
//other fields
context.AddDocument(document, indexable.Culture != null ? new CultureExecutionContext(indexable.Culture) : null);

After building and publishing the code it's working perfectly fine and I get the result into the SOLR query.

azure-cdn-sitecore

Happy Sitecoreing 😊

Comments

Popular posts from this blog

Sitecore Installation Error: Failed to Start Service 'Sitecore Marketing Automation Engine'

Import CSV Data in Sitecore Using PowerShell: Part-3

Error: Method Through Reflection is Not Allowed after Applying Sitecore Hotfix