Examine Custom Index is not getting rebuilt every time I publish a node
Hi,
I created a custom examine index in order to use the custom fields of a document type and also to order by a custom date instead of the default updateDate. Everything works fine.
Now i am using CMSImport, to import content to my site. From what i saw, the ExternalIndex is getting refreshed but the Custom index not. When i unpublish or unpublish a content, the ExternalIndex documents number is changing, the CustomIndex not.
So, do i have to force reindex on publish and unpublish manually? And if yes, how to do it? Is there any sample?
How the ExternalIndex is getting refreshed on every publish and unpublish, even more on massive imports using CMSImport? I created a component to rebuild my index on ContentSevice.Published and ContentSevice.UnPublished as follows
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class SubscribeToNewsArticleIndexRefreshComposer : ComponentComposer<NewsArticleIndexRefreshComponent>
{
//this automatically adds the component to the Components collection of the Umbraco composition
}
public class NewsArticleIndexRefreshComponent : IComponent
{
private readonly ILogger _logger;
private readonly IExamineManager _examineManager;
private readonly IndexRebuilder _indexRebuilder;
private readonly IAppPolicyCache _runtimeCache;
public NewsArticleIndexRefreshComponent(ILogger logger, IExamineManager examineManager, AppCaches appCaches, IndexRebuilder indexRebuilder)
{
_logger = logger;
_examineManager = examineManager;
_indexRebuilder = indexRebuilder;
_runtimeCache = appCaches.RuntimeCache;
}
// initialize: runs once when Umbraco starts
public void Initialize()
{
// subscribe to content service published event
ContentService.Published += ContentService_Published;
ContentService.Unpublished += ContentService_Unpublished;
}
// terminate: runs once when Umbraco stops
public void Terminate()
{
// unsubscribe on shutdown
ContentService.Published -= ContentService_Published;
ContentService.Unpublished -= ContentService_Unpublished;
}
private void ContentService_Published(Umbraco.Core.Services.IContentService sender, Umbraco.Core.Events.ContentPublishedEventArgs e)
{
RebuildIndex();
}
private void ContentService_Unpublished(Umbraco.Core.Services.IContentService sender, Umbraco.Core.Events.PublishEventArgs<Umbraco.Core.Models.IContent> e)
{
RebuildIndex();
}
private void RebuildIndex()
{
bool validated = ValidateIndex("NewsArticleIndex", out var index);
if (!validated)
return;
validated = ValidatePopulator(index);
if (!validated)
return;
_logger.Info<NewsArticleIndexRefreshComponent>("Rebuilding index '{IndexName}'", index.Name);
//remove it in case there's a handler there already
index.IndexOperationComplete -= Indexer_IndexOperationComplete;
//now add a single handler
index.IndexOperationComplete += Indexer_IndexOperationComplete;
try
{
//clear and replace
index.CreateIndex();
var cacheKey = "temp_indexing_op_" + index.Name;
//put temp val in cache which is used as a rudimentary way to know when the indexing is done
_runtimeCache.Insert(cacheKey, () => "tempValue", TimeSpan.FromMinutes(5));
_indexRebuilder.RebuildIndex(index.Name);
}
catch (Exception ex)
{
//ensure it's not listening
index.IndexOperationComplete -= Indexer_IndexOperationComplete;
_logger.Error<NewsArticleIndexRefreshComponent>(ex, "An error occurred rebuilding index");
}
}
private bool ValidateIndex(string indexName, out IIndex index)
{
if (!_examineManager.TryGetIndex(indexName, out index))
{
_logger.Error(GetType(), "NewsArticleIndexRefreshComponent | | Message: {0}", $"No index found by name < NewsArticleIndex >");
return false;
}
return true;
}
private bool ValidatePopulator(IIndex index)
{
if (_indexRebuilder.CanRebuild(index))
return true;
_logger.Error(GetType(), $"The index {index.Name} cannot be rebuilt because it does not have an associated {typeof(IIndexPopulator)}");
return false;
}
private void Indexer_IndexOperationComplete(object sender, EventArgs e)
{
var indexer = (IIndex)sender;
_logger.Debug<NewsArticleIndexRefreshComponent>("Logging operation completed for index {IndexName}", indexer.Name);
//ensure it's not listening anymore
indexer.IndexOperationComplete -= Indexer_IndexOperationComplete;
_logger.Info<NewsArticleIndexRefreshComponent>($"Rebuilding index '{indexer.Name}' done.");
var cacheKey = "temp_indexing_op_" + indexer.Name;
_runtimeCache.Clear(cacheKey);
}
}
And in order the CustomIndex is getting the data from a GetAll() function which is
But unfortunately on the following line, I am getting a Null reference exception, probably the IPublishedCache is not available due to the publishing procedure? I don't really know
var publishedArticles = contentHelper.GetByXPath("//homeDocType/newsCategory/newsArticle")?.ToList();
So how the ExternalIndex is getting refreshed without locks and problems?
I have similar problem with my custom member index.
On Save action (in backoffice or programmatically), my custom index doesn't rebuild so I cannot find new members in my search page until I manually rebuild the index.
I had to modify my Custom Index Creator as follows.
Now I have my custom index always updated.
Adriano
using Examine;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Util;
using System.Collections.Generic;
using Umbraco.Core.Logging;
using Umbraco.Core.Services;
using Umbraco.Examine;
using Umbraco.Web.Search;
namespace AF.Examine.Index.Tools.For.UmbracoV8.Creators
{
public class AFMembersIndexCreator : UmbracoIndexesCreator
{
private readonly IProfilingLogger _profilingLogger;
private readonly ILocalizationService _languageService;
private readonly IPublicAccessService _publicAccessService;
private readonly IMemberService _memberService;
private readonly IUmbracoIndexConfig _iUmbracoIndexConfig;
// Since Umbraco 8 has dependency injection out of the box, we can use it to inject
// the different services that we need.
public AFMembersIndexCreator(IProfilingLogger profilingLogger,
ILocalizationService languageService,
IPublicAccessService publicAccessService,
IMemberService memberService,
IUmbracoIndexConfig umbracoIndexConfig) : base(profilingLogger, languageService, publicAccessService, memberService, umbracoIndexConfig)
{
_profilingLogger = profilingLogger;
_languageService = languageService;
_publicAccessService = publicAccessService;
_memberService = memberService;
_iUmbracoIndexConfig = umbracoIndexConfig;
}
// Noticed that we return a collection of indexes? Technically you
// can create multiple indexes in an indexCreator :) You can have a look at
// UmbracoIndexesCreator.cs in the CMS core and see how the CMS does that.
public override IEnumerable<IIndex> Create()
{
// create my AFMembersIndex definitions
return new[] { CreateAFMembersIndex() };
}
private IIndex CreateAFMembersIndex()
{
var AFMembersIndex = new UmbracoMemberIndex(
"AFMembersIndex",
new FieldDefinitionCollection(
new FieldDefinition("memberId", FieldDefinitionTypes.FullText),
new FieldDefinition("memberNodeName", FieldDefinitionTypes.FullText),
new FieldDefinition("memberLoginName", FieldDefinitionTypes.FullText),
new FieldDefinition("memberEmail", FieldDefinitionTypes.FullText),
new FieldDefinition("memberName", FieldDefinitionTypes.FullText),
new FieldDefinition("memberSurname", FieldDefinitionTypes.FullText),
new FieldDefinition("memberIntTel", FieldDefinitionTypes.FullText),
new FieldDefinition("memberFax", FieldDefinitionTypes.FullText),
new FieldDefinition("memberCel", FieldDefinitionTypes.FullText)
),
CreateFileSystemLuceneDirectory("AFMembersIndex"),
new StandardAnalyzer(Version.LUCENE_30),
ProfilingLogger,
UmbracoIndexConfig.GetMemberValueSetValidator());
return AFMembersIndex;
}
}
}
Examine Custom Index is not getting rebuilt every time I publish a node
Hi,
I created a custom examine index in order to use the custom fields of a document type and also to order by a custom date instead of the default updateDate. Everything works fine.
Now i am using CMSImport, to import content to my site. From what i saw, the ExternalIndex is getting refreshed but the Custom index not. When i unpublish or unpublish a content, the ExternalIndex documents number is changing, the CustomIndex not.
So, do i have to force reindex on publish and unpublish manually? And if yes, how to do it? Is there any sample?
/Thomas
How the ExternalIndex is getting refreshed on every publish and unpublish, even more on massive imports using CMSImport? I created a component to rebuild my index on ContentSevice.Published and ContentSevice.UnPublished as follows
And in order the CustomIndex is getting the data from a GetAll() function which is
But unfortunately on the following line, I am getting a Null reference exception, probably the IPublishedCache is not available due to the publishing procedure? I don't really know
So how the ExternalIndex is getting refreshed without locks and problems?
Any help please? This is urgent... I need to find a way to reindex the custom index on after publish event without errors.
Thanks
Hi Thomas,
I have similar problem with my custom member index. On Save action (in backoffice or programmatically), my custom index doesn't rebuild so I cannot find new members in my search page until I manually rebuild the index.
Have you find a solution for this problem?
Thank you
Adriano
SOLVED
I had to modify my Custom Index Creator as follows.
Now I have my custom index always updated.
Adriano
is working on a reply...