I have a legacy site 4.7.1 and im trying to use a filtered
search functionality using Examine, im searching through content, and
one of the properties is a MNTP which in the searh results returns a
comma delimited list id Ids.
If one property is set to a node it
filters fine, but if two are selected it fails. How do i handle a MNTP
result using Examine? Here is what i have so far :-
@{ var filterList = Request["filters"]; //1122,1133,1347
var searcher = ExamineManager.Instance.SearchProviderCollection["InternalSearcher"];
var criteria = searcher.CreateSearchCriteria(IndexTypes.Content); var query = criteria.NodeTypeAlias("Partner"); query = query.Not().Field("umbracoNaviHide", 1.ToString());
if (!string.IsNullOrEmpty(filterList)) { string[] attIds = filterList.Split(','); query.And().GroupedOr(new List { "attributes" }, attIds);
}
var results = searcher.Search(query.Compile()); }
As you can see here, Examine is returning the feld 'attributes' but how do i check if the filtered set of ids i have match?
Having recently started to get to grips with Examine in Umbraco, the general accepted approach is to change the way the data gets indexed in Lucene through the Examine API by taking advantage on the indexing events that can be used to change the way the data gets stored in Lucene.
That is to say there is nothing wrong with your query - but more in which the way the content is indexed in Umbraco by default.
When data is indexed it is tokenised into search terms and tokens are generally defined by splitting field values using spaces and other whitespace such as line breaks, tabs etc. Therefore with a multi-node tree picker because content items are delimited by a comma, Lucene indexes the whole picker value as a single token and so your search fails to execute as you would reasonably expect.
What you need to do is change the MNTP field data to replace the commas with a space, this way each item in the picker will be tokenised correctly and allow your searcher to function how you want.
Ismail Mayat over at the Cogworks has some good blogs on how this can be achieved by using an Examine event called GatheringNodeData. His series also exposes some other events and tricks and tips for working with Examine within Umbraco.
Thanks for the detailed response, sorry its taken so long for a reply.
I have gone over the blog post but im struggling to implement how to do it. Where should this code sit? I currently have tried a class within the App_Code folder but it doesnt seem to get hit, the results are still returning in a comma list.
I have just ried creating a seperate project class library and creating a dll and including this in the bin folder of my site but alas again the out put is still in a comma delimted string, my class so far is below:
namespace ExamineEvents { /// <summary> /// Summary description for ExamineEvents /// </summary> public class ExamineEvents : ApplicationBase { public ExamineEvents() { ExamineManager.Instance.IndexProviderCollection["InternalSearcher"].GatheringNodeData += ExamineEvents_GatheringNodeData; }
//grab the current data from the Fields collection var mntp = e.Fields["attributes"]; //let's get rid of those commas! mntp = mntp.Replace(",", " "); //now put it back into the Fields so we can pretend nothing happened! e.Fields["attributes"] = mntp;
}
private void AddContentsFileds(IndexingNodeDataEventArgs e) { var fields = e.Fields; var combinedFields = new StringBuilder(); foreach (var keyValuePair in fields) { combinedFields.AppendLine(keyValuePair.Value); } e.Fields.Add("contents", combinedFields.ToString()); }
} }
Where should i add this code? Is there anything else i need to do? Ive re indexed the indexes but again no joy.
Apologies for the belated reply - I hadn't notice you had replied to the thread until just now. Looking over your code the only issue I can see is that your trying to attach your event to the Searcher and not the Indexer which may well be why its not working. Other than that the code looks fine.
depending on if you want the indexer to change the way your internal or external index is stored.
Pretty sure that if you make this change and drop the updated code into your APP_CODE or bin folder if a compiled DLL then you should start to see the results you expect after you have restarted Umbraco and initiate a re-index of the relevant IndexSets.
Examine search how to handle MNTP result Field
Hi
I have a legacy site 4.7.1 and im trying to use a filtered search functionality using Examine, im searching through content, and one of the properties is a MNTP which in the searh results returns a comma delimited list id Ids.
If one property is set to a node it filters fine, but if two are selected it fails. How do i handle a MNTP result using Examine? Here is what i have so far :-
@{
var filterList = Request["filters"]; //1122,1133,1347
var searcher = ExamineManager.Instance.SearchProviderCollection["InternalSearcher"];
var criteria = searcher.CreateSearchCriteria(IndexTypes.Content);
var query = criteria.NodeTypeAlias("Partner");
query = query.Not().Field("umbracoNaviHide", 1.ToString());
if (!string.IsNullOrEmpty(filterList))
{
string[] attIds = filterList.Split(',');
query.And().GroupedOr(new List { "attributes" }, attIds);
}
var results = searcher.Search(query.Compile());
}
As you can see here, Examine is returning the feld 'attributes' but how do i check if the filtered set of ids i have match?
Having recently started to get to grips with Examine in Umbraco, the general accepted approach is to change the way the data gets indexed in Lucene through the Examine API by taking advantage on the indexing events that can be used to change the way the data gets stored in Lucene.
That is to say there is nothing wrong with your query - but more in which the way the content is indexed in Umbraco by default.
When data is indexed it is tokenised into search terms and tokens are generally defined by splitting field values using spaces and other whitespace such as line breaks, tabs etc. Therefore with a multi-node tree picker because content items are delimited by a comma, Lucene indexes the whole picker value as a single token and so your search fails to execute as you would reasonably expect.
What you need to do is change the MNTP field data to replace the commas with a space, this way each item in the picker will be tokenised correctly and allow your searcher to function how you want.
Ismail Mayat over at the Cogworks has some good blogs on how this can be achieved by using an Examine event called GatheringNodeData. His series also exposes some other events and tricks and tips for working with Examine within Umbraco.
Hi Tim
Thanks for the detailed response, sorry its taken so long for a reply.
I have gone over the blog post but im struggling to implement how to do it. Where should this code sit? I currently have tried a class within the App_Code folder but it doesnt seem to get hit, the results are still returning in a comma list.
I have just ried creating a seperate project class library and creating a dll and including this in the bin folder of my site but alas again the out put is still in a comma delimted string, my class so far is below:
namespace ExamineEvents
{
/// <summary>
/// Summary description for ExamineEvents
/// </summary>
public class ExamineEvents : ApplicationBase
{
public ExamineEvents()
{
ExamineManager.Instance.IndexProviderCollection["InternalSearcher"].GatheringNodeData += ExamineEvents_GatheringNodeData;
}
void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
{
AddContentsFileds(e);
//grab the current data from the Fields collection
var mntp = e.Fields["attributes"];
//let's get rid of those commas!
mntp = mntp.Replace(",", " ");
//now put it back into the Fields so we can pretend nothing happened!
e.Fields["attributes"] = mntp;
}
private void AddContentsFileds(IndexingNodeDataEventArgs e)
{
var fields = e.Fields;
var combinedFields = new StringBuilder();
foreach (var keyValuePair in fields)
{
combinedFields.AppendLine(keyValuePair.Value);
}
e.Fields.Add("contents", combinedFields.ToString());
}
}
}
Where should i add this code? Is there anything else i need to do? Ive re indexed the indexes but again no joy.
Hi Neil,
Apologies for the belated reply - I hadn't notice you had replied to the thread until just now. Looking over your code the only issue I can see is that your trying to attach your event to the Searcher and not the Indexer which may well be why its not working. Other than that the code looks fine.
There this line here...
should be...
or
depending on if you want the indexer to change the way your internal or external index is stored.
Pretty sure that if you make this change and drop the updated code into your APP_CODE or bin folder if a compiled DLL then you should start to see the results you expect after you have restarted Umbraco and initiate a re-index of the relevant IndexSets.
Tim
is working on a reply...