So today while answering a question on the Umbraco forum I thought that what I was going on about is something that more people might want to hear about. And really, I do like the sound of my own (virtual) voice…
Understanding Lucene.Net from Examine
For this I’m going to be looking at the Lucene.Net implementation of Examine, and this is agnostic of whether you’re using UmbracoExamine or Examine.LuceneEngine.
To get started you should familiarize yourself a bit with the Lucene Query Parser Syntax, as that’s what we’re using internally to get the data back from Lucene.Net.
Also, we’re going to be working with the Fluent API for Examine, so fell free to read up on that here and here. With Examine we’ve made it easy to see what the Lucene query you’re building up is as you’re working with the Fluent API, in fact if you to a .ToString() call on the ISearchCriteria instance you’ll be able to see what you’re search query looks like (we’ve also got some other information in the result of that method call too).
So you can see what’s been generated, let’s build a query and dissect it:
var criteria = searcher.CreateSearchCriteria(IndexTypes.Content); criteria = criteria.NodeName("Hello").And().NodeTypeAlias("world").Compile(); Console.WriteLine(criteria.ToString()); //+(+nodeName:Hello +nodeTypeAlias:world) +__IndexType:content
So this is what we've got, a total of three conditions… But wait, there’s only two conditions that I entered right?
Not quite, Examine has some smarts built into it around what you’re searching on and it’ll add that restriction on your behalf. This is so you don’t get results back from a different index type in your query. Note: If you don’t specify the IndexType then this condition wont be added for your.
Also, to ensure that all your entered queries don’t get killed by the IndexType (a problem in earlier Examine builds) we combine everything you enter into a GroupedAnd statement.
Let’s have a look at the parts we did request, and how they are comprised:
Ok, so what we've got here is our two conditions which we've added using Examine. Each is an AND (or in Lucene terminology SHOULD) and this is denoted by the +. Next we have a field name, in this case either nodeName or nodeTypeAlias. Youl’ll notice back in our Fluent API query we actually generated all of that using the build in methods, rather than having to use more magic strings. Next there is a : to indicate where the field name ends. Lastly we have the term which we’re going to search against, either Hello or world.
So essentially it’s built up of BOOLEAN_OPERATION&FieldName:Term (the & is so it’s slightly readable).
This was a brief look at how the Fluent API for Examine will turn your typed query into a Lucene query that is then searching.
With this knowledge you should be better able to design complex queries, use mixed conditionals and just plain go crazy.