Orchard Harvest 2015 – Search API
In which we learn how much of a narcissist Sébastien really is: he watches his own sessions from previous years, and learns a lot doing so ;)
Search in Orchard is implemented through three modules:
- Orchard.Indexing detects changes from content handlers, processes changes in a background task, and configures indexes in the dashboard.
- Lucene implements indexed contents and search over the Lucene library.
- Orchard.Search displays search results on the front end and in the dashboard.
In Orchard.Search, there is a recipe that sets up an index on all pages and blog posts in the site. It’s a quick and easy way to setup search on your site. The other way of doing this is to manually create an index from the dashboard and then configure search to use it.
Search can also be configured to display items in search results using a different display type than the default “Summary”. This makes it possible to completely customize the rendering of search results by using the corresponding alternate template.
It is possible to create a separate index to use with search from the dashboard. This is useful if the front-end has unpublished contents that should not be shown on the front-end, but should absolutely be found when searching from the dashboard.
Creating separate indexes can also be useful if you want to implement targeted search, for example a knowledge base search that is different from a product search.
If you want to implement custom indexing of contents from code, you can create a handler and call OnIndexing<SomePart> with a Lambda that defines how to index a given part. This is how the TermsPart in taxonomies can index taxonomy terms. This is also how the body part gets sanitized to remove HTML tag markup before indexing.
Luke.net is an application that reads Lucene indexes. This is a nice way to check if and how an index was built.
ISearchService lets you perform searches on an Orchard index from code, while IIndexProvider lets you implement custom indexes instead of Lucene.
Sébastien showed how to create a custom search API controller that queries the index, applies some faceted filters and custom order, then outputs the results as a JSON document. The faceted search is done using GetBits on the search builder. You can ask the result of that for the number of results that match any particular value for the facet. This is how destinationido.com implemented its faceted search.
Finally, Seb showed how to do geolocated searches, which I had no idea Lucene could do. But of course you can, as long as you have coordinates: just check each index entry from your search builder for the distance with the point you are trying to filter around.
All these custom filters are being applied against the index, rather than the actual database, so it’s all very fast. This is in fact fairly close to the map/reduce APIs that are available in DecentCMS and the Orchard 2.0 prototypes.
And… the jetlag is finally kicking in. Unless it’s Sébastien who made me so sleepy. This blog post was written while sleeping, so if you spot any glaring inaccuracies, let’s blame it on that.
UPDATE: the video is online.