EPiServer Find has extensive support for indexing all kinds of objects and types. However the support for dictionaries is a bit limited. I got a question a couple of weeks ago regarding how to search/filter on the keys or values of a dictionary (and not on a specific value for a specific key). The default dictionary support in EPiServer Find doesn’t support this but it is not that hard to achieve.

There are two steps that we need to do accomplish this. First we need to create a JsonConverter that handles the serialization/deserialization of dictionary objects and extracts the keys and values into separate properties that we later can query on. Thereafter we create an IInterceptContract that allows us to intercept and modify the default JsonDictionaryContract and where we can set our custom dictionary JsonConverter. I will leave out the implementation details but at Dictionary2Find you can fetch your own copy of the code.

How to use the Dictionary2Find extension

At startup register the contract interceptor:

client.Conventions.ContractResolver.ContractInterceptors.Add(new DictionaryConvention());

Given that you have indexed the following object:

public class Document
{
	public Document()
	{
		MetadataDictionary = new Dictionary<string, string>();
	}
    
    public string Name { get; set; }

    public Dictionary<string, string> MetadataDictionary { get; set; }
}

You can filter on all documents having a specific key

client.Search<Document>()
	.Filter(x => x.MetadataDictionary.Keys.Match("key"))
	.GetResult();

You can of course also specify keys/values when using the free text search:

client.Search<Document>()
	.For("keyvalue")
	.InField(x => x.MetadataDictionary.Keys)
	.GetResult();

If you want to use these features with the EPiServer CMS integration simply change client in the examples to SearchClient.Instance.

Dictionary2Find also supports searching on GeoLocation and Attachments in the value-field. Check out the test stories for an example of how to do GeoLocation filtering or see this gist.

Update

The dictionary convention registration has been added as an IClientConventionsExtension:

client.Conventions.AddDictionaryConventions();