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.
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.
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)
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
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.
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.
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.
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.
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.
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!
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.
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
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!
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.
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
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.
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.
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:
And my search page code looks like this:
It may not be easy/possible to limit your index but it's not too hard to filter your results.
@Andrew, +1, I came to the same conclusion as well :-)
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();
is working on a reply...