Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Damian Green 452 posts 1433 karma points
    Sep 24, 2014 @ 13:22
    Damian Green
    0

    How to force examine to rebuild the index of a child node

    I am using the ExamineEvents_GatheringNodeData event to add supplementary info to a node from the parents of the node i am indexing.

    The structure i have to make this easier to understand is

    Region

    --Location

    ----JobTypeA

    ----JobTypeB

    I have the Region and Location also in the included document types to index so these trigger indexing when published also.

    When i publish a Job node the GatheringNodeData runs for thenode and i can update fine, but when a location or region changes i need the descendant jobs to update their indexes to match the new Location or Region.

    I have tried the content service publish, and the examine re-index node and it doesnt seem to trigger the re-index for the Job nodes.

    Maybe some fluke but it did happen once - but its not happened again.

    I dont want to trigger a full index rebuild as that wont really work well either (too slow to update indexes as i have searches running off these).

    Here are the two ways i have tried to do this:

    void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
        {
    string nodeType;
            e.Fields.TryGetValue("nodeTypeAlias", out nodeType);
    
            if (string.IsNullOrEmpty(nodeType)) return;
    
            var contentSvc = _context.Services.ContentService;
    
            switch (nodeType)
            {
                case "JobRegion":
                    var jobRegion = contentSvc.GetById(e.NodeId);
    
                    //Get all the locations to pick up the new names in the region 
                    //                    
                    foreach (var locationUpdate in jobRegion.Children())
                    {
                        //Republish all the jobs to pick up the new names in the location
                        //
                        foreach (var job in locationUpdate.Children())
                        {
                            contentSvc.Publish(job);
    
                            if (job.ContentType.Alias == typeof(JobA).Name)
                                indexer.ReIndexNode(job.ToXml(), typeof(JobA).Name);
                            else if (job.ContentType.Alias == typeof(JobB).Name)
                                indexer.ReIndexNode(job.ToXml(), typeof(JobB).Name);
                        }
                    }
    

    The indexer is the serach index - indexer = ExamineManager.Instance.IndexProviderCollection["JobsIndexer"];

    I have tried just the content service publish, just the re-index and both together in different orders and its still not working correctly.

    Any ideas why its not triggering reliably?

    Thanks

  • Damian Green 452 posts 1433 karma points
    Sep 24, 2014 @ 13:42
    Damian Green
    0

    I have also tried

    (sender as BaseIndexProvider).ReIndexNode(job.ToXml(), typeof(Job).Name);

    but that didnt change anything.

    The GatheringNodeData is triggered fine on the publish of the Location or region but the subsequent repubish and redindex requests are not doing anything.

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Sep 24, 2014 @ 13:54
    Dave Woestenborghs
    2

    I have taken a different approach.

    Instead of trying to reindex the child nodes during the ExamineEvents_GatheringNodeData of the JobRegion node, you should hook in to the published event of the JobRegion node. 

    Below is a piece of code that works for umbraco 4.11 and is tweaked a bit to match your code

    namespace MyNameSpace
    {
        using Examine;
    
        using umbraco.cms.businesslogic;
        using umbraco.cms.businesslogic.web;
    
        using Umbraco.Core;
        using Umbraco.Web;
    
        using UmbracoExamine;
    
        /// <summary>
        ///     The document events.
        /// </summary>
        public class DocumentEvents : IApplicationEventHandler
        {
            #region Public Methods and Operators
    
            /// <summary>
            /// The on application initialized.
            /// </summary>
            /// <param name="httpApplication">
            /// The http application.
            /// </param>
            /// <param name="applicationContext">
            /// The application context.
            /// </param>
            public void OnApplicationInitialized(UmbracoApplication httpApplication, ApplicationContext applicationContext)
            {
            }
    
            /// <summary>
            /// The on application started.
            /// </summary>
            /// <param name="httpApplication">
            /// The http application.
            /// </param>
            /// <param name="applicationContext">
            /// The application context.
            /// </param>
            public void OnApplicationStarted(UmbracoApplication httpApplication, ApplicationContext applicationContext)
            {
                Document.AfterPublish += this.DocumentAfterPublish;
                Document.AfterUnPublish += this.DocumentAfterUnPublish;
                Document.AfterDelete += this.DocumentAfterDelete;
            }
    
            /// <summary>
            /// The on application starting.
            /// </summary>
            /// <param name="httpApplication">
            /// The http application.
            /// </param>
            /// <param name="applicationContext">
            /// The application context.
            /// </param>
            public void OnApplicationStarting(UmbracoApplication httpApplication, ApplicationContext applicationContext)
            {
            }
    
            #endregion
    
            #region Methods
    
    
    
            /// <summary>
            /// The document_ after publish.
            /// </summary>
            /// <param name="sender">
            /// The sender.
            /// </param>
            /// <param name="e">
            /// The e.
            /// </param>
            private void DocumentAfterPublish(Document sender, PublishEventArgs e)
            {
                if (sender.ContentType.Alias == "JobRegion")
                {
                    this.ReIndexChildren(sender.Id);
                }
            }
    
    
    
            /// <summary>
            /// The re index.
            /// </summary>
            /// <param name="nodeid">
            /// The nodeid.
            /// </param>
            private void ReIndexChildren(int nodeid)
            {
                var jobRegion = new Document(nodeid);
    
                foreach (var locationUpdate in jobRegion.Children())
                    {
                        //Reindex all the jobs to pick up the new names in the location                    
                        foreach (var job in locationUpdate.Children())
                        {
    
                           ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"].ReIndexNode(job.ToXDocument(false).Root, IndexTypes.Content);
    
                        }
                    }
            }
    
            #endregion
        }
    }
  • Damian Green 452 posts 1433 karma points
    Sep 24, 2014 @ 14:24
    Damian Green
    100

    Jackpot!

    I didn't need to re-write - although I did wonder about using the publishing service.

    I noticed from your code what I had done wrong - in the Re-Index method it was asking for a type and i was passing in the document type alias! What it needed was the IndexType - IndexTypes.Content. Though it was a bit odd asking for the document type.

    So ive added that and it now works! Not very clear from the variable name and it ought to use the Enum imho.

    Anyway - everything indexing great now! :)

    Thanks for chiming in! :)

    Damian

  • Damian Green 452 posts 1433 karma points
    Sep 24, 2014 @ 14:26
    Damian Green
    0

    Not sure which is the best practice - either to use the publish event or what i've done...? Will leave it for now and see.

  • Damian Green 452 posts 1433 karma points
    Sep 24, 2014 @ 14:30
    Damian Green
    0

    As an aside Dave - not sure if you know but i believe the PublishingStrategy.Published is the proper way to hook into events now and then loop through the e.PublishedEntities

    Damian

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Sep 24, 2014 @ 14:48
    Dave Woestenborghs
    0

    Hi Damian,

    As pointed out my code is from 4.11 project. The PublishingStragey is introduced in v6

    Dave

  • Damian Green 452 posts 1433 karma points
    Sep 24, 2014 @ 15:12
    Damian Green
    0

    Hi Dave,

    Yeah - i was just adding some extra info... No worries. :)

    Damian

Please Sign in or register to post replies

Write your reply to:

Draft