Customizing the SharePoint 2010 Search User Experience

Customizing the SharePoint 2010 Search User Experience

Professional SharePoint 2010 Development bookWhile the SharePoint 2010 Search out-of-the-box user interface is very intuitive and useful for information workers, power users can create their own search experiences. SharePoint Server 2010 includes many search-related web parts for power users to create customized search experiences, including Best Bets, refinement panel extensions, featured content, and predefined queries. Figure 6-21 shows the standard Search web parts.

IT pros or developers can configure the built-in search web parts to tailor the search experience. As a developer, you can also extend the web parts, to change the behavior of built-in web parts on search results pages. Instead of building new web parts, developers can build onto the functionality of existing ones.

In addition, query logging is now available from customized search web parts, and from any use of the Query object to query the Search Service.

Figure 6-21

Example: New Core Results Web Part

Let’s walk you through the creation of a new search web part in Visual Studio 2010. (The full code is included with Code Project 6-P-1, and is courtesy of Steve Peschka.) This web part inherits from the CoreResultsWebPart class and displays data from a custom source. The standard CoreResultsWebPart part includes a constructor and then two methods that we will modify in this example.

The first step is to create a new WebPart class. Create a new web part project that inherits from the CoreResultsWebPart class. Override CreateChildControls to add any controls necessary for your interface, and then override CreateDataSource. This is where you get access to the “guts” of the query. In the override, you will create an instance of a custom datasource class you will build. 

class MSDNSample : CoreResultsWebPart

    {

        

        public MSDNSample()

        {

            //default constructor;        }

        

        protected override void CreateChildControls()

        {

            base.CreateChildControls();

        

            //add any additional controls needed for your UI here

        }

        

        protected override void CreateDataSource()

        {

            //base.CreateDataSource();

            this.DataSource = new MyCoreResultsDataSource(this);

        }

The second step is to create a new CoreResultsDatasource class. In the override for CreateDataSource, set the DataSource property to a new class that inherits from CoreResultsDataSource. In the CoreResultsDataSource constructor, create an instance of a custom datasource view class you will build. No other overrides are necessary.

public class MyCoreResultsDataSource : CoreResultsDatasource

        {

            public MyCoreResultsDataSource(CoreResultsWebPart ParentWebpart)

                : base(ParentWebpart)

            {

                //to reference the properties or methods of the web part

                //use the ParentWebPart parameter

        

                //create the View that will be used with this datasource

                this.View = new MyCoreResultsDataSourceView(this,”MyCoreResults”);

            }

        }

The third step is to create a new CoreResultsDatasourceView class. Set the View property for your CoreResultsDatasource to a new class that inherits from CoreResultsDatasourceView. In the CoreResultsDatasourceView constructor, get a reference to the CoreResultsDatasource so that you can refer back to the web part. Then, set the QueryManager property to the shared query manager used in the page.

public class MyCoreResultsDataSourceView : CoreResultsDatasourceView

        {

        

             public MyCoreResultsDataSourceView       (SearchResultsBaseDatasource DataSourceOwner, string ViewName)

                     : base(DataSourceOwner, ViewName)

            {

                //make sure we have a value for the datasource

                if (DataSourceOwner == null)

                {

                    throw new ArgumentNullException(“DataSourceOwner”);

                }

        

                //get a typed reference to our datasource

                 MyCoreResultsDataSource ds =       this.DataSourceOwner as MyCoreResultsDataSource;

        

                //configure the query manager for this View

 

                 this.QueryManager = SharedQueryManager.GetInstance       (ds.ParentWebpart.Page).QueryManager;

            }

You now have a functional custom web part displaying data from your custom source. In the next example, we take things one step further to provide some custom query processing.

Example: Adding Sorting to Your New Web Part

The CoreResultsDataSourceView class lets you modify virtually any aspect of the query. The primary way to do that is in an override of AddSortOrder. This class provides access to SharePointSearchRuntime class, which includes: KeywordQueryObject, Location, and RefinementManager.

The code example below adds sorting by overriding AddSortOrder. (The full code is included with Code Project 6-P-1, courtesy of Steve Peschka.)

public override void AddSortOrder(SharePointSearchRuntime runtime)

            {

                #region Ensure Runtime

                //make sure our runtime has been properly instantiated

                if (runtime.KeywordQueryObject == null)

                {

                    return;

                }

                #endregion

        

                //remove any other sorted fields we might have had

                runtime.KeywordQueryObject.SortList.Clear();

        

                 //get the datasource so we can get to the web part

                //and retrieve the sort fields the user selected

                 SearchResultsPart wp =      this.DataSourceOwner.ParentWebpart as SearchResultsPart;

                string sortField = wp.SortFields;

        

                //check to see if any sort fields have been provided

                if (!string.IsNullOrEmpty(sortField))

                {

                    //if posting back, then use the value from the sort drop-down

                    if (wp.Page.IsPostBack)

                    {

                        //get the sort direction that was selected

                        SortDirection dir =

                             (wp.Page.Request.Form[SearchResultsPart  .mFormSortDirection] ==   “ASC” ?

                            SortDirection.Ascending : SortDirection.Descending);

        

                        //configure the sort list with sort field and direction

                         runtime.KeywordQueryObject.SortList.Add    (wp.Page.Request.Form[SearchResultsPart.mFormSortField],

                            dir);

                    }

 

                    else

                    {

                        //split the value out from its delimiter and

                        //take the first item in descending order

                         string[] values = sortField.Split(“;”.ToCharArray(),     StringSplitOptions.RemoveEmptyEntries);

                         runtime.KeywordQueryObject.SortList.Add(values[0],     SortDirection.Descending);

                    }

                }

                else  //no sort fields provided so use the default sort order

                    base.AddSortOrder(runtime);

The KeywordQueryObject class is what’s used in this scenario. It provides access to key query properties like: 

EnableFQL
RowLimit
EnableNicknames
SearchTerms
EnablePhonetic
SelectProperties
EnableStemming
SortList
Filter
StartRow
QueryInfo
SummaryLength
QueryText
TrimDuplicates
Refiners
. . . and many more

To change the sort order in your web part, first remove the default sort order. Get a reference to the web part, as it has a property that has the sort fields. If the page has been posted back, then get the sort field the user selected. Otherwise, use the first sort field the user selected. Finally, add the sort field to the SortList property.

To allow sorting, you also need to provide fields on which to sort. Ordering can be done with DateTime fields, Numeric fields, or Text fields where: HasMultipleValues = false, IsInDocProps = true, and MaxCharactersInPropertyStoreIndex > 0.

You can limit the user to only selected fields by creating a custom web part property editor. This uses the same process as in SharePoint 2007: inherit from EditorPart and implement IWebEditable. The custom version of EditorPart in this example web part uses a standard LINQ query against the search schema to find properties.

This article is excerpted from chapter 6 "Search" of the book Professional SharePoint 2010 Development by Tom Rizzo, Reza Alirezaei, Jeff Fried, Paul Swider, Scot Hillier, Kenneth Schaefer (ISBN: 978-0-470-52942-3, Wrox, 2010, Copyright Wiley Publishing Inc.)

Tags:

Comments

One response to “Customizing the SharePoint 2010 Search User Experience”

  1. Anonymous says:

    Hello,
    I need to show the percent of similartity between the word that I am serching for and the result in SP like (The word that Iam searching for is “Document Folder” and the result is “Document Folder ” – 100% similarity )
    another example Iam searching for is “Document Folder” and the result is “Document Managment” – 530% similarity )
    and so on
    can you please help

Leave a Reply

Your email address will not be published. Required fields are marked *