Archive

Archive for June, 2013

Getting custom ranking model for People Search working

June 3, 2013 2 comments

Today I’ve created a custom ranking model for the SharePoint 2010 People Search. There are a lot of examples online on how to create a custom ranking model and how to use it (for example http://blog.petergerritsen.nl/2010/10/12/people-search-use-a-custom-ranking-model-to-search-in-added-profile-properties/).

When you’ve added the custom ranking model to SharePoint, you can use it using a query string parameter called rm1. But that doesn’t really look nice, and when people don’t use that query string variable, they will end up using the default raking model again.

It does look like you can set it as the default raking model by tweaking the properties of the Core Result WebPart. It has a property to set the default ranking model, but…. It doesn’t seem to work for the People Search. The People Search will keep setting the ranking model back to the default people search ranking model MainPeopleModel.

So where does this leave us… We can still use the query string option and we can off course always use a JavaScript on the page to redirect using the query string variable if it is not set. But, that does mean we can get useless hits on the page and useless search queries (since we redirect the user right after their request). This is something I really don’t like… It causes load on the servers which should not be there.

To get around this issue, I’ve created a small WebPart. The WebPart allows you to provide the ID (GUID) of a custom ranking model and during the initialization of the page, it sets the custom ranking model for the query manager of the page. This ensures that the search query will use your custom ranking model, without performing useless queries or redirecting the user. The code to get this working you can find below. Please note, I’ve added my own logging module to this code and you probably want to add your own logging logic J.

using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using PeterHeibrink.SP2010.Intranet.Core.Logging;
using Microsoft.Office.Server.Search.Query;
using Microsoft.Office.Server.Search.WebControls;
using Microsoft.SharePoint.WebPartPages;
using WebPart = System.Web.UI.WebControls.WebParts.WebPart;

namespace PeterHeibrink.SP2010.Intranet.WebParts.WebParts.SetSearchRankingModel
{
/// <summary>
/// This class implements a <see cref=”WebPart”/> which allows for
/// overriding the ranking model ID.
/// </summary>
/// <remarks>
/// This WebPart is needed for applying a custom ranking profile for people search.
/// For people search, the default ranking model setting in the WebPart properties is
/// not persisted and cannot be set by updating the WebPart XML.
/// </remarks>

[ToolboxItemAttribute(false)]
public class SetSearchRankingModel : WebPart
{

#region WebPart Properties

/// <summary>
/// This property allows for setting the Ranking Model ID
/// </summary>
/// <remarks>
/// This is used to force the search webparts on the page to use
/// an alternative ranking model. This is done because the people search 
/// webpart will otherwise not use a custom ranking model.
/// </remarks>
[WebBrowsable(true), WebDisplayName(“Ranking model ID”),
WebDescription(“This should be the ID of the ranking model”)]
[Personalizable(PersonalizationScope.Shared),
SPWebCategoryName(“Ranking model”)]
public string RankingModelId 

{
   get { return _rankingModelId; }
set { _rankingModelId = value; }

}

private string _rankingModelId = string.Empty;

 #endregion

#region Overriden events

/// <summary>
/// This event will ensure the <see cref=”QueryManager”/> will use a custom
/// ranking profile.
/// </summary>
/// <param name=”e”>Event arguments</param>
protected override void OnInit(EventArgs e)
{
// Makse sure the property is set
if (string.IsNullOrEmpty(RankingModelId))
{

LogService.LogWarning(
    LogCategory.WebPart,
“An WebPart has been added to override the Ranking Model of a Search Query, but no Ranking Model ID has been provided.”);
return;

}

// Get the current query manager and make sure it is available
QueryManager queryManager = SharedQueryManager.GetInstance(this.Page).QueryManager;
if (queryManager == null)
{
LogService.LogError(
LogCategory.WebPart,
“An WebPart has been added to override the Ranking Model of a Search Query, but there is no Query Manager available.”);

    return;
}

// Set the custom ranking model for all locations
foreach (LocationList locationList in queryManager)
foreach (Location location in locationList)
location.RankingModelID = RankingModelId;

LogService.LogMedium(
        LogCategory.WebPart,
“An WebPart has been added to override the Ranking Model of a Search Query, the locations have been updated with the new ranking model.”);

base.OnInit(e);

}

/// <summary>
/// This event will add a control to the page displaying the ranking model setting.
/// </summary>
/// <remarks>
/// The Ranking model is displayed to allow for easy checking if the webpart is added on the page
/// by accounts without permissions.
///
</remarks>
 

protected override void CreateChildControls()
{
Controls.Add(new  LiteralControl(string.Format(“<!– Ranking model set to: ‘{0}’–>”, RankingModelId)));

}

#endregion

}

}

Categories: Development, SharePoint
Ben Prins

What I want to remember about SharePoint

blog.frederique.harmsze.nl

my world of work and user experiences

Bram de Jager - Coder, Speaker, Author

Office 365, SharePoint and Azure