Adding fuzzy filtering to the EPiServer Find Fluent API
A few days back I got a question of how to do fuzzy filtering on a field using the Fluent API in EPiServer.Find. Some had seen that Elasticsearch had the possibility to do FuzzyQueries and that the core classes in EPiServer.Find had an implementation of this query but that there wasn’t a corresponding filter in either Elasticsearch or EPiServer.Find for doing this. However this is quite easily done anyway and it will enable you to do queries like:
Writing a QueryFilter
In Elasticsearch there is the possibility of wrapping a query in a filter using the Query Filter. The latest official release for EPiServer.Find does however not have an implementation of it so we have to start by creating a new Filter class mapping to the QueryFilter implementation in Elasticsearch. Filter classes in EPiServer.Find are simply classes implementing Filter and when passed to the Json serializer are serialized to the corresponding Elasticsearch filter. So we create a QueryFilter class implementing Filter and a Json converter for serializing it:
Now we have the possibility to do Fuzzy filtering, or any other query filtering, by simply passing the query class to the query filter. Now it is time to extend the filter extensions to get that fluent querying that we love.
Writing a Filter extension for strings to do fuzzy matching
A filter extension is simply an extension of the core type that we want to extend, in our case string, and that returns a DelegateFilterBuilder. The DelegateFilterBuilder in turn is created by passing a mapping from the ‘field name’ to a filter. EPiServer.Find will automatically resolve the internal Elasticsearch field name for filters for you so all you have to do is the mapping (the filter field mappings are non tokenized so your query has to match the complete value of the field):
Voila, now we have a Fuzzy extension that we can use in our queries.
Wrapping it up
Importing the QueryFilter and FilterExtensions into your workspace you are now able to do that fluent search request you always wanted: