In one of my previous posts I wrote about extending the content processing pipeline by developing a custom content enrichment service to modify the managed properties of the crawled items before they are added to the search index. This post is a kind of follow up on that.
Suppose sites can be tagged by one or more terms. Users are able to set and modify these terms.
On a page with a content search webpart and a refinement panel users can search content and use the refinement panel to find sites (also) tagged with these terms.
These terms are stored in a propertybag, added to the indexed properties keys and exposed by a managed property.
The propertybag values for three different sites are:
To point some values out: The term ‘site02|..’ is used twice (at site 01 and site 02) and the term ‘site04|..’ is used once (at site 03).
The managed property is added to the refinement panel and configured to use the multi-value refinement item display template.
As you can see in the above image the managed property containing the terms isn’t really multivalued, because of the values of the propertybag are stored as a single string. Notice the missing ‘site04|…’ in the refinementpanel, which is present in the propertybag shown in the PowerShell image. Creating the managed property as a multivalued property won’t help you create a real multivalued property.
A content search webpart in conjunction with this refinement panel will show only one site at the time when eg selecting ‘site02|..’ which is used twice and should result Site 01 and Site 02:
Refining results based on these values will only match sites when they are tagged with the same terms in the same order: the exact same string.
A possible solution for this is to extend the content processing pipeline by a service. This service picks up the propertybag value and splits the values, in this case the terms, and inserts the separate values into the multivalued managed property.
The basics of how to set up a custom content enrichment service is explained in the post ‘Issue sorting links and documents based on Title‘
Only the code for the service itself is shown. This is the service which accepts requests from the content processing component.
private const string SiteTagProperty = "ITIdeaSiteTag"; private const int UnexpectedType = 1; private const int UnexpectedError = 2; private readonly ProcessedItem processedItemHolder = new ProcessedItem { ItemProperties = new List<AbstractProperty>() }; public ProcessedItem ProcessItem(Item item) { processedItemHolder.ErrorCode = 0; processedItemHolder.ItemProperties.Clear(); try { // Iterate over each property received and locate the property we configured the system to send. foreach (var property in item.ItemProperties) { if (property.Name.Equals(SiteTagProperty, StringComparison.Ordinal)) { var siteTag = property as Property<List<string>>; if (siteTag != null && siteTag.Value != null && siteTag.Value.Count > 0) { string[] propValues = siteTag.Value.First().Split(';'); List<string> listpropValues = propValues.ToList(); Property<List<string>> newSiteTagProp = new Property<List<string>>(); newSiteTagProp.Name = SiteTagProperty; newSiteTagProp.Value = listpropValues; processedItemHolder.ItemProperties.Add(newSiteTagProp); } } } } catch (Exception) { processedItemHolder.ErrorCode = UnexpectedError; } return processedItemHolder; }
The item.ItemProperties contain all the input properties received by the service. These input properties will be configured by PowerShell.
The code checks if the ITIdeaSiteTag property contains multiple terms, splits it and adds it to a list of property values and returns the changed value to the content processing component.
Configure the Search Service Application to use the Content Enrichment service by using PowerShell, for an example see this post. Don’t forget to set a meaningful trigger otherwise every item will be passed this service.
Run a full crawl.
The refinement panel now shows a nice set of single values, notice the presence of ‘site04|..’ here:
When using the refinement panel in conjunction with a content search webpart, two sites will be displayed when selecting e.g. ‘site02|..’ as expected:
Summary
To make a multivalued propertybag a real multivalued managed property a custom content enrichment service can de developed to accomplish this.
After creating a multivalued managed property it can be used in e.g. a refinement panel.
The intention of this post was purely to demonstrate the technique, no changes has been made to make things look pretty 🙂
Note
Only one custom content enrichment service can be bound to a Search Service Application.
If you want more properties to be processed by the service you have to configure the InputProperties, OutputProperties and don’t forget the Trigger of the EnterpriseSearchContentEnrichmentConfiguration object to handle them all.