SharePoint 2013 No Code User Segment Search

I stated looking into the User Segmentation feature in SharePoint 2013. The idea is that you create query rules based off of a category of users and then change the search experience to better suit them. Some examples would be adjusting results based on the users language / location, providing different best bets based on a user's title, etc. The first step is to define the names of the segments. These are just entries in the Managed Metadata Service term store.

Here is an example from my test case. I just created two terms: English and French.

This is where most examples would ask you to create a custom web part. Here are two examples I looked at: Adaptive experiences in a Product Catalog in SharePoint 2013 using Facebook location data and User segmentation in SharePoint 2013

That web part will do a few things:

1. Look for a property to compare against user segments.

2. Check the term store to see if there is a match for the property.

3. Grab the guid of the matching term

4. Add the guid to a special query parameter

Step 1 is not really SharePoint specific. Steps 2 and 3 are fairly straight forward. So, I wanted to focus on part 4. How can you add a user segment to your query without adding a custom web part? What if you are using the REST API directly?

The key is how can you specify "UserSegmentTerms"

(dataProvider.Properties["UserSegmentTerms"] = userSegmentTerms.ToArray();)

in your query. UserSegmentTerms is not a property that you can just add as a part of the get request. UserSegmentTerms needs to be passed a part of KeywordQueryProperties

To pass the KeywordQueryProperties, we're going to use a post request and send a JSON object. I found Nadeem's blog a great place to get started here: How-To: PostQuery in SharePoint 2013 Search REST API and Tip - Handling HTTP 403 Forbidden when querying the Search REST Service using the PostQuery method .

Once we have our basic JSON post query working, we want to specify the KeywordQueryProperties. This is done by specifying "properties". There are some good examples here SharePoint Search REST API overview . If you scroll down to "Properties", you'll see an example of how to specify the KeyworkQueryProperties.

{'__metadata':{'type':'Microsoft.Office.Server.Search.REST.SearchRequest'},'Querytext':'sharepoint','Properties' : {     'results' : [          {               'Name' : 'sampleBooleanProperty',               'Value' :               {                    'BoolVal' : 'True',                    'QueryPropertyValueTypeIndex' : 3               }          },          {               'Name' : 'sampleIntProperty',               'Value' :                {                    'IntVal' : '1234',                    'QueryPropertyValueTypeIndex' : 2               }          }     ]}}

Now, what we need to do is to create the same property that would be submitted by dataProvider.Properties["UserSegmentTerms"] = userSegmentTerms.ToArray();). So, the Name will be UserSegmentTerms, the type will be a string array and the value will be a one element array with the guid of the term that defines our user segment.

Here is what my query look like if I want to specify the "French" user segment.

{'request':{'Querytext':'sharepoint','Properties' : {     'results' : [          {               'Name' : 'UserSegmentTerms',               'Value' :               {                    'StrArray' :  { 'results' : [ "3c2375ab-d09a-4f9a-9089-3ec0084192a9","3c2375ab-d09a-4f9a-9089-3ec0084192a9"] } ,                    'QueryPropertyValueTypeIndex' : 4               }          }     ]}}}

3c2375ab-d09a-4f9a-9089-3ec0084192a9","3c2375ab-d09a-4f9a-9089-3ec0084192a9 is the guid of my French term in the term store. You can see the guid in my first screen shot.

All that's left is to create Query Rules that will fire off of the user segment.

Comments

  • Anonymous
    November 10, 2014
    Hi Pete,

    quick question on this, firing the POST request would generate a different result set and we would need another webpart of display results from this query, correct ?
    this change wouldnt impact the OOB webpart response, that webpart would not get results based on the Query rule coz OOB the request goes to _vti_bin/client.svc/ProcessQuery and the REST API call will be to a different endpoint and also from HTTP stand point these will be 2 request going out. I am using resultscriptwebpart here for the search results.