Copied to clipboard

Flag this post as spam?

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


  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Aug 13, 2010 @ 13:22
    Ismail Mayat
    1

    GatheringNodeData examine event

    Guys,

    I am using code from Shannons cg10 demo and implementing GatheringNodeData method.  What I am trying to do is I have a product doc type, that has bunch of fields that are of type ultimate picker.  The ultimate picker takes parent doc as source and lists child pages below it.  

    The data in the umbraco product document will store umbraco node ids.  In the index i want to store a field value from the document selected by ultimate picker.  My question is not all the fields on that product doc are of type ultimate picker so do i have to handle them seperately or will they get indexed as well?  In my examine index config i am by default indexing all fields.

    So code so far is something like:

     

     if (e.IndexType == IndexTypes.Content)
                {
    
                    if (e.Node.UmbNodeTypeAlias() == productAlias)
                    {
    
                        //if this is a 'product' page look at ultimate picker params 
    
    
                        var node = new Node(e.NodeId);
                        // get all ultimate picker fields , get value then add to index acutal value
                        
    
                        //put the combined comments into this blog post's index
                        e.Fields.Add("somefile", actualvalue);
                    }
    
                }

     

     

    Regards

    Ismail

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Aug 16, 2010 @ 12:59
    Ismail Mayat
    1

    In answer to my own question you do not need to handle the other fields separately, however you will get conflicts if you are adding fields so you need to ensure you give them another name, in my case i had field alias duration so i added it as __duration as it was already in as duration.

    Regards

    Ismail

  • Rich Green 2246 posts 4008 karma points
    Sep 03, 2010 @ 08:35
    Rich Green
    0

    Hi Ismail,

    This is exactly what I need to do too.

    How did you get on, do you possibly have any code you could share?

    Many thanks

    Rich

     

  • Ismail Mayat 4511 posts 10090 karma points MVP 2x admin c-trib
    Sep 03, 2010 @ 11:22
    Ismail Mayat
    3

    Rich,

    my examine gathering node class looks like this

    using System.Collections.Generic;
    using umbraco.BusinessLogic;
    using Examine;
    using UmbracoExamine;
    using umbraco.presentation.nodeFactory;
    using System.Text;
    using Umbraco_Site_Extensions.automation;
    namespace Umbraco_Site_Extensions.examineExtensions
    {
        public class ExamineEvents:ApplicationBase
        {
    
            private const string WoiIndexer = "WOIIndexer";
            private const string ProductAlias = "Product";
            private readonly List<string> _ultimatePickerAliases = new List<string>{"theme","country","budgetFrom","budgetTo","participantFrom","participantTo","durationFrom","durationTo","periodFrom","periodTo"};
    
            private const string NumericProperties =
                "budgetFrom,budgetTo,participantFrom,participantTo,durationFrom,durationTo,periodFrom,periodTo";
            /// <summary>
            /// handles special cases for indexing of product properties
            /// that are of type ultimate picker we want the actual value not node id in the index
            /// </summary>
            public ExamineEvents()
            {
                //Add event handler for 'GatheringNodeData' on our 'WOI'
                ExamineManager.Instance.IndexProviderCollection[WoiIndexer].GatheringNodeData
                    += ExamineEvents_GatheringNodeData;
    
            }
    
            /// <summary>
            /// Event handler for GatheringNodeIndex.
            /// This will fire everytime Examine is creating/updating an index for an item
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
            {
                //check if this is 'Content' (as opposed to media, etc...)
                if (e.IndexType == IndexTypes.Content)
                {
                    if (e.Node.UmbNodeTypeAlias() == ProductAlias)
                    {
                        //if this is a 'product' page look at ultimate picker params 
                        var node = new Node(e.NodeId);
                        foreach (var ultimateAlias in _ultimatePickerAliases) {
                            var propertyValue = node.GetPropertyValue(ultimateAlias);
                            if(propertyValue!=string.Empty)
                            {
                                if(propertyValue.Contains(","))
                                {
                                    string[] propValues = propertyValue.Split(new[] {','});
                                    var sbConcatValue=new StringBuilder();
                                    foreach (var propValue in propValues)
                                    {
                                        sbConcatValue.Append(GetFieldValue(e, propValue, ultimateAlias));
                                        sbConcatValue.Append(",");
                                    }
    
                                    e.Fields.Add("__" + ultimateAlias, sbConcatValue.ToString().TrimEnd(','));
    
                                }
                                else
                                {
                                    e.Fields.Add("__" + ultimateAlias,GetFieldValue(e, propertyValue, ultimateAlias));
                                }
                            }
                        }
    
                    }
                    AddToContentsField(e);
                }
    
            }
    
            private void AddToContentsField(IndexingNodeDataEventArgs e)
            {
                Dictionary<string, string> fields = e.Fields;
                var combinedFields = new StringBuilder();
                foreach (KeyValuePair<string, string> keyValuePair in fields)
                {
                    combinedFields.AppendLine(keyValuePair.Value);
                }
                e.Fields.Add("contents",combinedFields.ToString());
            }
    
            /// <summary>
            /// get ultimate picker field acutal value not the id of target 
            /// </summary>
            /// <param name="e"></param>
            /// <param name="propertyValue"></param>
            /// <param name="luceneFieldAlias"></param>
            /// <returns></returns>
            private string GetFieldValue(IndexingNodeDataEventArgs e, string propertyValue,string luceneFieldAlias)
            {
                int nodeId = 0;
                int.TryParse(propertyValue, out nodeId);
    
                    var n= new Node(nodeId);
                    //node does not exist but we have numeric value
                    if(n.Id!=0){
                        if (NumericProperties.Contains(luceneFieldAlias))
                        {
                            //have to pad out to get lucene range queries to work
                            int i = 0;
                            int.TryParse(n.Name, out i);
    
                            return i.ToString("D6");
                        }
                        else{
                            return n.Name;
                        }
                    }
                    return nodeId.ToString("D6");         
    
            }
        }
    }

    Regards

     

    Ismail

  • Rich Green 2246 posts 4008 karma points
    Sep 03, 2010 @ 11:35
    Rich Green
    0

    Hi Ismail,

    Thanks alot, I'll let you know how I get on.

    Cheers

    Rich

  • Rich Green 2246 posts 4008 karma points
    Sep 03, 2010 @ 22:25
    Rich Green
    0

    I've got the Indexer event wired in, many thanks Ismail/Aaron/Shannon.

    Ismail, I think what you're doing is more complex than my issue as you have mulitiple pickers on the same doc type. 

    I only have one so in theory I assume I need to split each csv into it's own index.

    <attributePicker><![CDATA[1057,1058,1060]]></attributePicker>

    And then I'll be able to use some type of "and" criteria to work out id this the search for 1057 and 1060 matches?

    Would be good if I can confirm I'm going down the correct path...

    Cheers

    Rich

  • Carlos Sardo 7 posts 27 karma points
    Sep 07, 2010 @ 10:33
    Carlos Sardo
    0

    Gents,

    Just a quick question about the ExamineEvents class (posted above)... After you add it to your project (UmbracoExtensions in my case) do you need to do any change to the ExamineSettings.config or to the ExamineIndex.config? I am using this class to solve a very similar issue (just like the original post), although, after all the changes to the  (my) DocumentAlias, properties, etc... it didn't work out for me. And I can't seem debug it as well...

            private const string WoiIndexer = "TheIndex";
            private readonly List<string> DocumentTypeAlias = new List<string> { "ProjectOverview", "ProjectPage" };
            private readonly List<string> _ultimatePickerAliases = new List<string> { "LeftBlocks", "MiddleBlocks", "RightBlocks" };

            private const string NumericProperties = "LeftBlocks,MiddleBlocks,RightBlocks";

    Hope to hear back from you soon.

    Cheers,

    Carlos

     

  • Rich Green 2246 posts 4008 karma points
    Sep 07, 2010 @ 10:34
    Rich Green
    0

    Hi Carlos,

    Which version of Examine are you running?

    Rich

  • Carlos Sardo 7 posts 27 karma points
    Sep 07, 2010 @ 10:37
    Carlos Sardo
    0

    Lucene.net.dll > File version: 2.9.2.1

    UmbracoExamine.dll > File version: 0.9.2.0

  • Rich Green 2246 posts 4008 karma points
    Sep 07, 2010 @ 10:41
    Rich Green
    0

    Hi,

    I have the code above working with (shipped with Umbraco 4.5.2)

    Lucene.net.dll > File version: 2.9.2.2

    UmbracoExamine.dll > File version: 0.9.2.2

    Not sure if this makes a difference.

    What is your exact problem, does the project not compile or are the indexes not being added?

    Rich

     

  • Carlos Sardo 7 posts 27 karma points
    Sep 07, 2010 @ 10:49
    Carlos Sardo
    0

    Hi Rich,

    Everything compiles great, although, when I check the Index (using Luke) I don't see the __LeftBlocks, etc (...) fields. I would expect them to be generated as well. Like I told before, I can't debug the class also. Therefore, I am not really sure if this custom UmbracoExamie event handler is being fired up.

    Cheers,

    Carlos

  • Rich Green 2246 posts 4008 karma points
    Sep 07, 2010 @ 10:59
    Rich Green
    0

    Hi Carlos,

    Two things I can suggest.

    One is to make sure you are referencing the correct indexer from the ExamineSettings.Config file (I made this mistake)

      private const string WoiIndexer = "TheIndex";

    Second, add a debug to the log to see if the event is getting fired (you'll need to reference using umbraco.BusinessLogic;)

      Log.Add(LogTypes.Notify, -1, "We are watching yooou from examine event");

    I couldn't get debugging to work either (I didn't try too hard), so I just used the log to debug as above.

    Best of luck

    Rich

     

  • Carlos Sardo 7 posts 27 karma points
    Sep 07, 2010 @ 11:11
    Carlos Sardo
    0

    Hi Rich,

    That was it... I was referencing my IndexSet not the Indexer. It works now!

    Thank you for your quick help!

    Cheers,

    Carlos

  • Rich Green 2246 posts 4008 karma points
    Oct 22, 2010 @ 15:44
    Rich Green
    0

    Ismail,

    After you've added the special indexes for MNTP in the GatheringNodeData event, how & when do you remove them?

     

    Say if I deselect a value from a MNTP field surely I have to remove the index?

    Rich

     

  • Aaron Powell 1708 posts 3046 karma points c-trib
    Oct 23, 2010 @ 00:26
    Aaron Powell
    0

    Yeah it'll be updated. It runs off the Umbraco XML so if that changes then the index should change.

  • Thomas 49 posts 78 karma points c-trib
    Feb 25, 2011 @ 12:52
    Thomas
    0

    Hey - following worked for me, had a problem as we needed to query the ParentID on Media objects.
    ParentID does not appear to be an attribute of the actual media item, so simple adding this to the ExamineIndex.config did not work.
    Seems you have to get the containing (I guess is the right word?) node for the Media item, and then stuff that into your index as a new fields:

           private const string MAGAZINE_INDEXER_NAME = "MagazineIndexer";

    public UmbracoExamineEvents()
    {
    var indexer = ExamineManager.Instance.IndexProviderCollection[MAGAZINE_INDEXER_NAME];
    indexer.GatheringNodeData += MagazineIndexer_OnGatheringNodeData;
    }

    /// <summary>
    /// Handles the OnGatheringNodeData event of the MagazineIndexer.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="Examine.IndexingNodeDataEventArgs"/> instance containing the event data.</param>
    void MagazineIndexer_OnGatheringNodeData(object sender, IndexingNodeDataEventArgs e)
    {
    if (e.IndexType != IndexTypes.Media)
    return;

    e.Fields.Add("_parentID", e.Node.Attribute("parentID").Value);
    }
  • Marie 14 posts 36 karma points
    Apr 20, 2012 @ 16:35
    Marie
    0

    Hi

    I know its been a while since this original post but I am now do something similar to this where I can access properties of a node on the GatheringNodeData event but rather than using the umbraco.presentation.nodeFactory, I am now using the umbraco.NodeFactory  ....

    private void IndexShadowProduct(IndexingNodeDataEventArgs e, Node node)
            {
                string origNodeID = e.Fields["umbracoInternalRedirectId"].ToString();

                if (!string.IsNullOrEmpty(origNodeID))
                {
                    Node origNode = new Node(int.Parse(origNodeID));
                    e.Fields["bodyText"] = origNode.GetProperty("bodyText").Value;
                }

            }

    However, I can get a handle on the property but the Value is throwing an exception:

    '((new System.Collections.Generic.Mscorlib_CollectionDebugView(origNode.PropertiesAsList)).Items[0]).Value' threw an exception of type 'System.NullReferenceException'

    Any ideas? Thanks in advance

    Marie

  • Anton Oosthuizen 206 posts 486 karma points
    Mar 11, 2013 @ 08:14
    Anton Oosthuizen
    0

    For the hell of me I couldn’t get this to work. I could see the index happening and the fields getting loaded with the “__”. But could not retrieve the information with a search.

     

    Then I went and removed the fields instead of adding a new “__” and replaced the values with the retrieved value. Then it worked. What was I missing here. Have a look at the data below and look at the country field If I searched for 1161 I got information back from examine if I searh for "South Africa" I there were no returns.

    Why couldnt I retrive any info  with the pre-value with a double underscore 

     

    if (propertyValue != string.Empty)

                            {

                                if (propertyValue.Contains(","))

                                {

                                    string[] propValues = propertyValue.Split(new[] { ',' });

                                    var sbConcatValue = new StringBuilder();

                                    foreach (var propValue in propValues)

                                    {

                                        sbConcatValue.Append(GetFieldValue(e, propValue, ultimateAlias));

                                        sbConcatValue.Append(",");

                                    }

                                    e.Fields.Remove(ultimateAlias); 

                                    e.Fields.Add(ultimateAlias, sbConcatValue.ToString().TrimEnd(','));

     

                                }

                                else

                                {

                                    e.Fields.Remove(ultimateAlias);

                                    e.Fields.Add(ultimateAlias, GetFieldValue(e, propertyValue, ultimateAlias));

                                }

                            }

     

    +[0]{[businessName, Full Throttle]}System.Collections.Generic.KeyValuePair<string,string>

    +[1]{[businessDescription, Aliquam sit amet sapien mauris! }System.Collections.Generic.KeyValuePair<string,string>

    +[2]{[country, 1161]}System.Collections.Generic.KeyValuePair<string,string>

    +[3]{[region, 1164,1165]}System.Collections.Generic.KeyValuePair<string,string>

    +[4]{[province, 1162]}System.Collections.Generic.KeyValuePair<string,string>

    +[5]{[cities, 1167]}System.Collections.Generic.KeyValuePair<string,string>

    +[6]{[id, 1219]}System.Collections.Generic.KeyValuePair<string,string>

    +[7]{[nodeName, Full Throttle]}System.Collections.Generic.KeyValuePair<string,string>

    +[8]{[updateDate, 2013-03-01T13:51:44]}System.Collections.Generic.KeyValuePair<string,string>

    +[9]{[writerName, admin]}System.Collections.Generic.KeyValuePair<string,string>

    +[10]{[loginName, fullthrottle]}System.Collections.Generic.KeyValuePair<string,string>

    +[11]{[email, [email protected]]}System.Collections.Generic.KeyValuePair<string,string>

    +[12]{[nodeTypeAlias, Client]}System.Collections.Generic.KeyValuePair<string,string>

    +[13]{[__country, South Africa]}System.Collections.Generic.KeyValuePair<string,string>

    +[14]{[__province, Gauteng]}System.Collections.Generic.KeyValuePair<string,string>

    +[15]{[__region, West Rand,East Rand]}System.Collections.Generic.KeyValuePair<string,string>

    +[16]{[__cities, Boksburg]}System.Collections.Generic.KeyValuePair<string,string>

     

     

    <ExamineLuceneIndexSets>

      <!-- The internal index set used by Umbraco back-office - DO NOT REMOVE -->

      <IndexSet SetName="InternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/Internal/"/>

     

      <!-- The internal index set used by Umbraco back-office for indexing members - DO NOT REMOVE -->

      <IndexSet SetName="InternalMemberIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/InternalMember/">

        <IndexAttributeFields>

          <add Name="id" />

          <add Name="nodeName"/>

          <add Name="updateDate" />

          <add Name="writerName" />

          <add Name="loginName" />

          <add Name="email" />

          <add Name="nodeTypeAlias" />

         

        </IndexAttributeFields>

        <IndexUserFields>

          <add Name="businessName" />

          <add Name="businessDescription" />

          <add Name="country" />

          <add Name="region" />

          <add Name="province" />

          <add Name="cities" />

          <add Name="__country" />

          <add Name="__region" />

          <add Name="__province" />

          <add Name="__cities" />

          <add Name="contents" />

        </IndexUserFields>

      </IndexSet>

     

      <!-- Default Indexset for external searches, this indexes all fields on all types of nodes-->

      <IndexSet SetName="ExternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/External/" />

    </ExamineLuceneIndexSe

Please Sign in or register to post replies

Write your reply to:

Draft