Copied to clipboard

Flag this post as spam?

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


  • Andrew Munro 78 posts 161 karma points
    Sep 13, 2012 @ 23:37
    Andrew Munro
    0

    Examine. Filtering to pages with templates but searching all content

    Hi All

    I am completley new to Examine and I'm trying to find a way to build a simple search page for our website. I've successfully set up a search page that pulls results based on search terms. 

    My problem is that we use nodes for content organization and layout on certain pages. For example, a product page has 2 child nodes, "LeftCol" and "RightCol". Within "LeftCol" and "RightCol" are "ContentBlock" nodes. This allows us to move "ContentBlocks between columns easily. "LeftCol",  "RightCol" and ContentBlocks are all node types that don't support templates. 

    With this in mind, when I go to create my search page, it currently searches through all nodes and returns the node's URL even if the page doesn't have a template. This is NOT the behaviour that I would like. I would like to see a list of pages (with templates) that contain the content that is being searched for. 

    My question is this. Is there any way to search all content in umbraco but return ONLY the nodes and URLs that have templates? Essentially I'm looking to search through all content but group any child nodes of templated pages into the pages themselves.

    Thanks!

     

     

  • Ismail Mayat 4511 posts 10092 karma points MVP 2x admin c-trib
    Sep 14, 2012 @ 10:57
    Ismail Mayat
    100

    Andrew,

    I am assuming that you want the content block nodes content to be searchable so only the pages containing the content blocks should appear in search results not the content blocks themselves which are in reality reusable content blocks?  If this is the case then you need to do the following.

    1. Those items without a template you need to add a property to them called umbracoNaviHide and set it to true / false and set value to true then republish them.(This will stop them appearing in search results)
    2.  Implement Gathering_Node data event and for those pages which have leftcol / right col -> content blocks get the actual content block content then inject it into a new field for the given page call the field whatever you like e.g contentBlock you may want to be specific leftColContentBlock etc
    Update the search query to also search on these new fields.  This will result in the placeholder content blocks from being ignored from the search results but the actual pages using the blocks will appear in the search results.  See below for some example code on how to implement gathering node data event
    using System;
    using System.Text;
    using System.Xml.Linq;
    using Examine;
    using umbraco.BusinessLogic;
    using umbraco.MacroEngines;
    using umbraco.presentation.nodeFactory;
    using Umbraco_Site_Extensions.automation;
    using UmbracoExamine;
    namespace Umbraco_Site_Extensions.examineExtensions
    {
        /// <summary>
        /// handle any lucene data injection here
        /// </summary>
        public class ExamineEvents:ApplicationBase
        {
            
            public ExamineEvents()
            {
                ExamineManager.Instance.IndexProviderCollection[Constants.ATGMainIndexerName].GatheringNodeData += ATGMainExamineEvents_GatheringNodeData;
               
            }
            void ATGMainExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
            {
                if (e.IndexType == IndexTypes.Content)
                {
                    var node = new Node(e.NodeId);
                    //do some stuff here
                }
            }
          
        }
    }
    You will need to modify also this needs to be new class file.
    Regards
    Ismail
  • Andrew Munro 78 posts 161 karma points
    Sep 14, 2012 @ 16:21
    Andrew Munro
    0

    Thank you for the reply. Thats exactly what I'm looking for. So this approach will essentially limit results to only templated pages but the event will do the work of searching content within? 

    I understand the umbracoNaviHide part but I'm unsure of where to proceed once I've created my node 

     var node = new Node(e.NodeId);
    //do some stuff here

    I am assuming that it's at this point that want to search the inner content and add it as a field to the parent node but I'm not sure where to start with that. 

    Thank you for your help!

     

  • Andrew Munro 78 posts 161 karma points
    Sep 14, 2012 @ 16:45
    Andrew Munro
    0

     To give a bit more context, here is the node tree. I would like to search a field within ContentBlock( Full TN3 Gallery, Product Brief, Building Widths(Placeholder), etc,) but if a result is found, I only ever want to show the product page (F-Series) that the content belongs to in the search results.


  • Ismail Mayat 4511 posts 10092 karma points MVP 2x admin c-trib
    Sep 17, 2012 @ 11:59
    Ismail Mayat
    0

    Andrew,

    Everything below F-Series needs to be hidden and not indexed you can actually thinking about do that by adding the types of the nodes eg Full Column and Full TN3 Gallery to the in the ExamineSettings file

     <ExcludeNodeTypes></ExcludeNodeTypes>

    Am I right in assuming that anything appearing below F-Series belongs to F-Series as content and needs to be searchable but as part of F-Series? If so then in the event you need to get the node and get all the children below it get the fields and add all the content to one string field using stringbuilder then inject the contents into the F-Series item in Examine. So doing a search for contents in the child nodes will result in the top level parent in this instance F-Series appearing in search results.

    Regards


    Ismail

  • Andrew Munro 78 posts 161 karma points
    Sep 17, 2012 @ 16:12
    Andrew Munro
    0

    Hi Ismail - Thank you so much for your help. After poking around in the GatherNodeData event for a while, I came up with the same process. It will take a bit of fine tuning but this will work as a great solution. Thank you.

  • Murray Roke 503 posts 966 karma points c-trib
    May 21, 2013 @ 04:56
    Murray Roke
    0

    If I wish to do something more convoluted to determine whether a node should be included in the index... am I able to do it programatically?

    I tried setting the GatheringNodeData.Cancel = true in the GatheringNodeData handler, but that didn't work.

  • Andrew Munro 78 posts 161 karma points
    May 21, 2013 @ 17:06
    Andrew Munro
    2

    Well umbraco would have its own GatheringNodeData (or similar) handler to populate the index automatically. By handling this even you are merely "adding on" to the data that's already there. At least, that's how I understand it. That being said, I'm not really sure where you would want to insert your logic. 

    As an alternate solution, you could just add a field to your indexd document that specifies if it can be searched or not. I did this so that I can only nodes that have templates.

    My GaterNodeData code looks like this:

    e.Fields.Add("HasTemplate", node.template > 0 ? "1" : "0");

    And my search page code looks like this:

     var filter = criteria
           .GroupedOr(GlobalTemplateLists.NonParentNodePageProperties, SearchTerms)
           .And()
           .Field("HasTemplate", "1") // <----- Relevant line
           .Compile();

    It may not be easy/possible to limit your index but it's not too hard to filter your results.

  • Murray Roke 503 posts 966 karma points c-trib
    May 22, 2013 @ 05:23
    Murray Roke
    0

    @Andrew, +1, I came to the same conclusion as well :-)

  • kaushal 5 posts 25 karma points
    Mar 21, 2016 @ 13:44
    kaushal
    0

    An easy way to filter only the pages which has templates assigned :

    var query = searchCriteria.GroupedOr(new string[] { "nodeName", "pageTitle","metaDescription","metaKeywords","hideFromSearch" }, searchTerm).Not().Field("template", "0").Compile();

Please Sign in or register to post replies

Write your reply to:

Draft