Copied to clipboard

Flag this post as spam?

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


  • Drew Garratt 44 posts 192 karma points
    Jan 24, 2013 @ 10:58
    Drew Garratt
    0

    Adding Relationships to Examine Index Sets

    Hi all,

    I'm currently working on a Job Board site for a client on Umbraco 4.10.1 and I'm using the relationships API to manage the attributes for each job. I'm in the early phases of laying out the site when I think I've spotted a shortfall in what I wanted to achive using Examine

    Using the uComponents MultiPickerRelations each job is related with bi-directional node to node relationships to each of it's key attributes.

    For Example "Engineering Manager" would be related to
    - Contract Type: "Permanent"
    - Hours: "Full Time"

    These relatonships should allow me to retrieve listings by there attributes such as well as keyword. Trouble is as far as I can see Examine dosen't by default index Relationships. Any ideas on the simplest way to implement indexing for this? I'd like to avoid looping though each individual search reasult for it's relations on each search as I have a feeling it's really going to slow things down.

    Thanks for any help anyone can give ^-^

  • Hendy Racher 863 posts 3849 karma points MVP 2x admin c-trib
    Jan 24, 2013 @ 11:44
    Hendy Racher
    100

    Hi Drew,

    How about an event handler that fires when Exmaine is indexing a job node to query it's relations data and add the associated attribute names space delimited into a new field ? (I'm guessing that you want to be able to search on an attribute name string like "Full Time", and return all matching jobs ?)

    Hopefully the following example may be of use (not tested this at all ! you'll need to update the values for your indexer name, job docType alias and the relationType alias, this also assumes that the child in the relationship is the attribute node).

    using System;
    using System.Linq;
    using Examine;
    using umbraco;
    using umbraco.businesslogic;
    using umbraco.cms.businesslogic.relation;
    
    public class IndexJobAttributes : ApplicationStartupHandler
    {
        public IndexJobAttributes()
        {
            ExamineManager.Instance.IndexProviderCollection["myIndexer"].GatheringNodeData += new EventHandler(IndexJobAttributes_GatheringNodeData);
        }
    
        private void IndexJobAttributes_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
        {
            if (e.IndexType == "content")
            {
                Node node = uQuery.GetNode(e.NodeId);
    
                if (node != null && node.NodeTypeAlias == "Job")
                {
                    e.Fields["jobAttributes"] = String.Join(
                                                            " ",
                                                            RelationType.GetByAlias("relateJobToAttribute")
                                                                        .GetRelations(node.Id)
                                                                        .Select(x => uQuery.GetNode(x.Child.Id).Name));
                }
            }
        }
    }
    
    
    

    HTH,

    Hendy

  • Drew Garratt 44 posts 192 karma points
    Jan 24, 2013 @ 13:33
    Drew Garratt
    1

    Hi Hendy,

    Thanks for this looks like the kind of thing I'm trying to do. With this kind of method I might even be able to break down diffrent relationships into diffrent collections.

    Still getting to grips with the C# end of Umbraco after spending years head down in XSLT without pause for breath. Will be sure to share my progress if I get a working solution in place.

    Thanks again,

    Drew

  • Drew Garratt 44 posts 192 karma points
    Feb 26, 2013 @ 14:00
    Drew Garratt
    0

    Hi again,

    After doing some work to bring my V6 solution up to speed I've gotten started with this exetension in ernest.
    Trouble is so far it dosen't seem to be pushing any values into my index, sad time.

    Any obvious reason anyone can spot why this might be not be returning anything?

     

    using System.Collections.Generic;
    using umbraco.BusinessLogic;
    using Examine;
    using UmbracoExamine;
    using umbraco.presentation.nodeFactory;
    using System.Text;
    using umbraco;
    using umbraco.cms.businesslogic.relation;
    
    namespace Client.classes
    {
        public class ExamineEvents : ApplicationBase
        {
            // Configuration variables
            // Target Indexer - Target Document Alias to be index - Target relationship aliases (to be looped though and added)
            private const string Indexer = "BootstrapENIndexer";
            private const string TargetDocumentAlias = "Textpage";
            private readonly List _relationAliases = new List { "TestRelation" };
    
            public ExamineEvents()
            {
                //Add event handler for 'GatheringNodeData' on our 'Indexer'
                ExamineManager.Instance.IndexProviderCollection[Indexer].GatheringNodeData
                    += ExamineEvents_GatheringNodeData;
            }
    
            //
            // Event handler for GatheringNodeIndex.
            //This will fire everytime Examine is creating/updating an index for an item
            void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
            {
                //Build Index Node
                umbraco.NodeFactory.Node theNode = new umbraco.NodeFactory.Node(e.NodeId);
    
                //check if this is 'Content' (as opposed to media, etc...)
                if (e.IndexType == IndexTypes.Content)
                {
                    //If the current node matches our targe alias
                    if (theNode.NodeTypeAlias == TargetDocumentAlias)
                    {
                        //For each relationship alias
                        foreach (var relationAlias in _relationAliases)
                        {
                            // Get relations by relation alias
                            RelationType relationType = RelationType.GetByAlias(relationAlias);
                            Relation[] relations = Relation.GetRelations(e.NodeId, relationType);
    
                            // For each realationship in our matched node
                            foreach (Relation relation in relations)
                            {
                                // Get the nodename of the related node
                                var relatedNode = uQuery.GetNode(relation.Id).Name;
                                if (relatedNode != string.Empty)
                                {
                                    //Add related node name to index list
                                    e.Fields.Add("__" + TargetDocumentAlias, relatedNode);
                                }
                            }
                        }
                    }
                    //Add all additional relations to index
                    AddToContentsField(e);
                }
            }
            private void AddToContentsField(IndexingNodeDataEventArgs e)
            {
                Dictionary fields = e.Fields;
                var combinedFields = new StringBuilder();
                foreach (KeyValuePair keyValuePair in fields)
                {
                    combinedFields.AppendLine(keyValuePair.Value);
                }
                e.Fields.Add("contents", combinedFields.ToString());
            }
        }
    }
    
  • Drew Garratt 44 posts 192 karma points
    Mar 07, 2013 @ 12:14
    Drew Garratt
    0

    Just in case it come up, tottally got it working... eventually

    Umbraco version 6.0.2

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Linq;
    using umbraco;
    using Umbraco.Core;
    using umbraco.BusinessLogic;
    using umbraco.cms.businesslogic;
    using umbraco.cms.businesslogic.web;
    using umbraco.cms.businesslogic.relation;
    using umbraco.NodeFactory;
    using Examine;
    using UmbracoExamine;
    
    namespace Umbraco.Extensions
    {
        public class ExamineEvents : ApplicationBase
        {
            // Configuration variables
            // Target Indexer - Target Parent (the partent of all the relationships we are indexing - Target Documents (all documents types that are related) - Target relationship aliases (to be looped though and added)
            private const string Indexer = "BootstrapENIndexer";
            private const string TargetParentDocument = "Job";
            private readonly List _TargetDocumentAliases = new List { "Job", "Company", "SpecialistArea", "Contract", "Hours", "Salary", "CareerLevel", "EducationLevel" };
            private readonly List _relationAliases = new List { "company", "SpecialistAreas", "contractType", "Hours", "salaryRange", "careerLevels", "educationLevels" };
    
            public ExamineEvents()
            {
                //Add event handler for 'GatheringNodeData' 
                ExamineManager.Instance.IndexProviderCollection[Indexer].GatheringNodeData += new EventHandler(ExamineEvents_GatheringNodeData);
            }
    
    
            // Event handler for GatheringNodeIndex.
            // This will fire everytime Examine is creating/updating an index for an item
    
            void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
            {
                //Build Index Node
                umbraco.NodeFactory.Node theNode = new umbraco.NodeFactory.Node(e.NodeId);
                //check if this is 'Content' (as opposed to media, etc...)
                if (e.IndexType == IndexTypes.Content)
                {
                    //For Each Document Type in target list
                    foreach (var TargetDocumentAlias in _TargetDocumentAliases)
                    {
                        // If current node matches our current Document Type
                        if (theNode.NodeTypeAlias == TargetDocumentAlias)
                        {
                            // Create string builder to add our relationships to as they are found
                            var comibineRelations = new StringBuilder();
    
                            // For each relationship alias in our target list
                            foreach (var relationAlias in _relationAliases)
                            {
                                // Get relations by relation alias
                                RelationType relationType = RelationType.GetByAlias(relationAlias);
                                Relation[] relations = Relation.GetRelations(e.NodeId, relationType);
    
                                // For each realationship in our matched node
                                foreach (Relation relation in relations)
                                {
                                    // Create a empty string varible to hold our related node id
                                    var relatedNode = string.Empty;
    
                                    // If the current node is the parent...
                                    if (theNode.NodeTypeAlias == TargetParentDocument)
                                    {
                                        //Store relations child ID in string
                                        relatedNode = relation.Child.Id.ToString();
                                    }
                                    else
                                    {
                                        //Store relations parent ID in string
                                        relatedNode = relation.Parent.Id.ToString();
                                    }
                                    if (relatedNode != string.Empty)
                                    {
                                        //Add each relation ID to string making sure to pad the values with space for Lucene
                                        comibineRelations.Append(relatedNode + " ");
                                    }
                                }
                            }
                            // Send our related string to be written out to the index
                            e.Fields.Add("relations", comibineRelations.ToString());
                        }
                    }
                    AddToContentsField(e);
                }
            }
    
            private void AddToContentsField(IndexingNodeDataEventArgs e)
            {
                Dictionary fields = e.Fields;
                var combinedFields = new StringBuilder();
                foreach (KeyValuePair keyValuePair in fields)
                {
                    combinedFields.AppendLine(keyValuePair.Value);
                }
                e.Fields.Add("contents", combinedFields.ToString());
            }
    
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft