Wednesday, 25 February 2015

What's in a .Name? SharePoint Online term set driven custom user profile properties in content search queries

How to utilise term set driven custom user profile properties in your content search web part queries with SharePoint Online

I've been working a lot on the publishing portals side of things recently and as part of this finding ways to drive a more user centric experience within traditional communication portal or intranet environments. For me this is one of the key uptake elements with any comms portal; you have to drive adoption, and if users aren't given some influence on what they see, such that it becomes personalised and relevant then they'll bypass it altogether and hop straight to whatever app or discovery/collaboration area they're looking for within SharePoint.

The problem

Using some very helpful reference material I had already been able to create, map and trigger a re-index of the user profile property store, so I could query the people index and see my new custom property in which I was holding my "personalised" news choices. I had also been able to successfully retrieve and edit that and other properties using JSOM code. Using this I had set up a custom property that maps to a term set (which is the same term set used in tagging articles, enabling matches between preferences and articles in the intranet environment).

The last issue was getting the content search web part query to use that new custom property as a filter on the articles being retrieved (and also using it to XRANK these articles so that they're more visible). I tried various combinations of {User.CustomProperty} and mapping the custom property to a RefinableString value (which of course didn't work, because when querying against the local search index for news articles you can't reference local people index content, the indexes don't talk to each other after all), none of which brought me any joy. Then I went back to the Microsoft documentation here which clearly states that I can use 
Any property from the user profile of the user who issued the query — for example, SPS-Interests, including custom properties.
Except that this was definitely NOT working. No filtering was taking place. Frustrating.

I then found the answer I was looking for when reading an extremely useful article by Mikael Svenson on some nice ways to build content search queries. He has an example for expanding multi-value properties into a chain of "OR" operation comparisons (in itself very handy even if I was only experimenting with a single value property at this stage) where he used the query "{|{User.SPS-Responsibility.Name}}"

What is that .Name doing there? Well SPS-Responsibility allows values from multiple term sets, and my custom property was mapped to a term set as well. If you look at the documentation on using terms in content search query then you see that just using the term gives you:
{Term} or {Term.ID} or {Term.IDNoChildren}
GUID of current site navigation node with a prefix of #0 — for example, #083e99dcb-7907-4dc9-abc8-b5614a284f1c. For example, this value can be used to query content of the managed property owstaxIdMetadataAllTagsInfo or owstaxIdProductCatalogItemCategory in a Product Catalog Site Collection.
Whereas using Term.Name gives you:
Label of the site navigation node — for example, Audio.
So by using {User.CustomProperty} I was basically trying to compare the GUID of the term to the label of the term (which is what was being returned by the article property). No surprise that it wasn't working as needed then!

The solution

A small alteration to {User.CustomProperty.Name} solved this immediately and the filters sprang into action as expected.

Final note

One additional thing to note here (which may be more or less frustrating depending on your goals) is that whilst JSOM to update user profile properties occurs immediately and content search queries using the {User.<property name>} query variable format use live values, the people search index will always lag behind this, so if you're using a query to retrieve that information locally rather than retrieving it through JSOM your users will see inconsistencies between values. Just something to be aware of, particularly given the hassle that keeping the user profile search index can be sometimes!

- rob