EPiServer  /  Find September 27, 2012

Type conditional filtering with EPiServer Find

Powerful new functionality in EPiServer Find's .NET API. Filter by type, with or without support for inheritance, within filter expressions.

EPiServer Find’s .NET API allows to filter by .NET/CLR type when searching and querying. For instance, let’s say we’ve indexed a bunch of objects representing animals. We can then find all animals using:

var result = client
    .Search<Animal>()
    .GetResult();

If we only want to find cats we change the type parameter:

var result = client
    .Search<Cat>()
    .GetResult();

But what if we want to find all animals except for dogs?

MatchType and MatchTypeHierarchy

We can then utilize one of two methods in a filter expression – MatchType and MatchTypeHierarchy. The first one matches by exact type match while the second matches any type in the object’s type hierarchy, that is it’s own type plus any class or interface that it inherits. So, to find all animals except for dogs we may add a filter such as this:

var result = client
    .Search<Animal>()
    .Filter(x => !x.MatchType(typeof(Dog)))
    .GetResult();

Another common use case is to add additional requirements to those documents that are of a specific type. For instance, it may be that if a CMS content object is versionable only the latest version should be matched. For our animal example it may be that we only want to find small animals meaning perhaps cats and small dogs. In other words we want to match all animals except for dogs unless the dog is small.

var result = client
    .Search<Animal>()
    .Filter(x => !x.MatchType(typeof(Dog)) | ((Dog)x).IsSmall.Match(true))
    .GetResult();

In the above example we use MatchType to filter by type. If there are subtypes of the Dog class we should instead use MatchTypeHierarchy. That method also comes in handy when filtering by interfaces. For instance, let’s say we have a Fish class which has a bunch of subtypes (Goldfish, Whale etc) and an interface that indicates that an animal is suitable as a pet. We could then exclude all fish excepts those that are good pets.

var result = client
    .Search<Animal>()
    .Filter(x => 
        !x.MatchTypeHierarchy(typeof(Fish)) 
        | x.MatchTypeHierarchy(typeof(IDomesticAnimal)))
    .GetResult();

More use cases

Both methods can be used in all filter expressions, meaning that they can also be used to boost certain objects using the BoostMatching method, in Filter facets, when dynamically building complex filters etc.

Notes and limitations

The methods for matching by type currently only works for the searched type and can't be used for nested properties/fields. That's however technically possible and I hope to see such functionality in the future. Also, the MatchTypeHierarchy method was added in a recent version of Find (1.0.0.224) so if you want to try it out, make sure you have the latest version.

PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.

Joel Abrahamsson

Joel Abrahamsson

I'm a passionate web developer and systems architect living in Stockholm, Sweden. I work as CTO for a large media site and enjoy developing with all technologies, especially .NET, Node.js, and ElasticSearch. Read more

Comments

comments powered by Disqus

My book

Want a structured way to learn EPiServer 7 development? Check out my book on Leanpub!

More about EPiServer Find