I ended up writing my own Examine search classes that made it up much easier to work with. I then backed this up with a Razor front-end. I'd love to make these available but as they were created for my company I can't open-source them as I don't own them :(
What I can say is that there are a number of problems to overcome:
- Finding examples of the configuration file formats for creating a custom index (last time I checked these weren't part of Umbraco documentation)
- The Examine fluent-API just didn't cut it from writing powerful queries and ended up creating wrappers for writing out queries in Lucene Query Language directly. This isn't easy, but is the only way to access more powerful features like using proper term modifiers for fuzzy matching.
- You need to escape or remove a lot of special characters from search queries that can easily break it
- I wanted to do stuff like only search starting from a given node (which requires using the path and wildcards) and return results between dates (particularly tricky!)
- You need to find a way of paginating results (I wrote Razor @helper classes for this)
- I had to integrate the lucene highlighter to highlight matches - again not simple
- The versions of Lucene.net and Examine bundled with Umbraco are well behind the latest versions. I ended up downloading the latest versions to use, but this is always risky. The newer versions also create indexes not compatible with older versions, so you need to know to delete all the old indexes first.
I can show an example of how I use it:
var searchProvider = ExamineManager.Instance.SearchProviderCollection["WebSearcher"];
var fields = new ExamineSearchFields();
fields.Add(new Field("nodeName"), new TermModifier("^3~0.8"));
fields.Add(new Field("heading"), new TermModifier("^2~0.8"));
fields.Add(new Field("bodyText"), new TermModifier("~0.8"));
ExamineSearcher searcher = new ExamineSearcher(fields, searchProvider);
searcher.StartNodeId = startNode;
searcher.AliasesToIgnore = new string[] { "Slider", "SiteSettings", "SystemPage", "Redirect" };
searcher.DateRangeToSearch = DateRange.FromQueryStringValue(dateRange);
var results = searcher.Search(searchTerm);
var pagedResults = new PagedExamineSearchResults(results, pageSize, page);
@foreach (var result in pagedResults.CurrentLuceneResultsSet)
{
////
}
Dan