In a recent project I’ve worked in we came up with the concept of Content Filters. In this post I will explain the general idea.
The rationale for creating the Content Filters is that to end users, configuring search results web parts can be hard. Even for SharePoint superusers and developers, you have to know a lot about how SharePoint search works, names of managed properties and fields etc. to be able to create advanced searches. We wanted to have a way for users to create powerful searches without having to configure search results web parts themselves.
We are storing queries into fields of the page, and then we have search results web parts provisioned on the page getting their queries from result sources which again are just picking up the query fields of the page. The result source query looks simply like this: {\Page.ContentFilterQuery1}
Since we have full control of the query, we can do cool things like letting the users write KQL, using fields on the page in different ways, include/exclude children terms for managed metadata searches, and more.
IntraDocumentStatus:Approved OR IntraDocumentStatus:Reviewed OR IntraDocumentStatus:"Pending Approval" OR IntraDocumentStatus:"Pending Reapproval" ContentTypeId:0x0101008C4E7537DBB64A9CB91C5D8112D44EA50113* owstaxIdIntraProductServiceMulti:#034ef7a04-73bf-4420-9e18-e8086d951de8
Code snippet: Example of a query picked up by the search web parts
We build the configuration model as a JSON object that is stored in a separate field on the page.
[{"_title":"Brochures","_model":{"_contentTypes":[{"Value":{"Id":"0x0101008C4E7537DBB64A9CB91C5D8112D44EA50113"}}],"_statuses":[{"Value":"Approved"},{"Value":"Reviewed"},{"Value":"Pending Approval"},{"Value":"Pending Reapproval"}],"_userInputQuery":"","_metadata":{}}},{"_title":"Media Content","_model":{"_contentTypes":[{"Value":{"Id":"0x0120D520A80800DF779D84BABF499C8C3CF9496D811B5001"}},{"Value":{"Id":"0x0101009148F5A04DDD49CBA7127AADA5FB792B00AADE34325A8B49CDA8BB4DB53328F21400C3AA00D5796C48639629BA0249C75A6D01"}},{"Value":{"Id":"0x0101009148F5A04DDD49CBA7127AADA5FB792B006973ACD696DC4858A76371B2FB2F439A008304A57B34E448A1B7D6A0C913EE1F8901"}}],"_statuses":[{}],"_userInputQuery":"","_metadata":{}}},{"_title":"Alerts","_model":{"_contentTypes":[{"Value":{"Id":"0x0101008C4E7537DBB64A9CB91C5D8112D44EA501010601"}}],"_statuses":[{"Value":"Approved"},{"Value":"Reviewed"},{"Value":"Pending Approval"},{"Value":"Pending Reapproval"}],"_userInputQuery":"","_metadata":{}}},{"_title":"Bulletins","_model":{"_contentTypes":[{"Value":{"Id":"0x0101008C4E7537DBB64A9CB91C5D8112D44EA501010602"}}],"_statuses":[{"Value":"Approved"},{"Value":"Reviewed"},{"Value":"Pending Approval"},{"Value":"Pending Reapproval"}],"_userInputQuery":"","_metadata":{}}},{"_title":"Lessons Learned","_model":{"_contentTypes":[{"Value":{"Id":"0x0101008C4E7537DBB64A9CB91C5D8112D44EA501010605"}}],"_statuses":[{"Value":"Approved"},{"Value":"Reviewed"},{"Value":"Pending Approval"},{"Value":"Pending Reapproval"}],"_userInputQuery":"","_metadata":{}}},{"_title":"Patents","_model":{"_contentTypes":[{"Value":{"Id":"0x010034F720BB1B564010999F8BAC472F7BEC0102"}}],"_userInputQuery":"","_metadata":{}}}]
Code snippet: Example of configuration object
Technically, the content filters are being created using JavaScript logic, building an array of content filter configurations. The logic is backed by a configuration file with names of managed properties, field names etc. that is being used to render the content filter form fields and “backend”. The frontend is using angular.js. The queries and fields are being saved to the fields on the page, without the end user knowing about it.
A very valid alternative to using search result web parts to pick up the queries is to roll your own search results. The benefit of this is that you can use the configuration object itself to perform the queries, and grab the results using the REST api. It’s an overall simpler approach and has less moving parts. The drawback of the approach is that you have to roll your own display templates for the results. With the result web parts approach we get the advantage of the SharePoint search toolstack, with result items, query rules, display templates etc.
Image above: The content filter web parts in display mode (with custom display template)