How to: Build a custom advanced search control for Enterprise Search
Posted
Monday, March 9, 2009 4:11 PM
by
CoreyRoth
It’s been a while since I have done a how to post, so I thought it was due time. I see request all of the time for people wanting to provide very specific custom advanced search capabilities. The AdvancedSearchWebPart is ugly and bit lacking, but luckily it is quite easy to build your own. For simplicity of today’s example, I built my custom search as a web user control. You can easily host this inside a web part by building your own SmartPart (or by using the one on CodePlex). In my example, I want a search page which lets me do normal keyword searches as well as search by product number and color. I also want to filter by results using specific scopes. This search control will go on a page inside the search center and use the existing results.aspx page to display the results.
However, before we begin, we must review a few concepts. First, to be able to search on a specific field, you must have a managed property mapped to the field. This applies if you are mapping to a site column or if you are mapping to some column in the database exposed via BDC. Secondly, you must take note of how the URL Syntax works for Enterprise Search. The reason for this is that we are simply redirecting the user to the results.aspx page via query string. This gives us custom functionality while keeping the out of the box search results. The URL syntax works similarly to the Keyword Syntax using the ‘k’ query string parameter.
Let’s first review the keyword syntax. For example, I want to search for anything with the word “Shirt” that is colored red in our “Online Products” scope. This is what the keyword syntax looks like.
Shirt Color:”Red” Scope:”Online Products”
This same query would be passed to results.aspx, using the ‘k’ query string parameter as such. You can URL encode it of course if necessary.
results.aspx?k=Shirt Color=”Red” Scope=”Online Products”
Pretty simple, right? So what does the user control look like? In my case, I have managed properties called Color and ProductNumber. Scope already has meaning in keyword syntax so it does not have to be accounted for.
It’s pretty simple, but allows me to use DropDownLists or whatever user control I want to use on each step. The code to generate the URL string is quite simple. You may need to take into account the proper URL to your results.aspx page in your Search Center.
protected void SearchButton_Click(object sender, EventArgs e)
{
Response.Redirect(GetQueryUrlSyntaxString());
}
/// <summary>
/// Returns a string in the url query syntax.
/// </summary>
/// <returns></returns>
private string GetQueryUrlSyntaxString()
{
System.Text.StringBuilder queryString = new System.Text.StringBuilder();
// append the path to results.aspx here
queryString.Append("results.aspx?k=");
// append the generic search term, followed by managed properties
// for example: shirts ProductNumber:"01232"
// for example: coats Color:"Red" Scope:"Retail Products"
if (!string.IsNullOrEmpty(SearchTextBox.Text))
queryString.Append(SearchTextBox.Text);
// write a space followed by the managed property and the value in quotes i.e.: ProductNumber:"01232"
if (!string.IsNullOrEmpty(ProductNumberTextBox.Text))
queryString.AppendFormat(" {0}:\"{1}\"", "ProductNumber", ProductNumberTextBox.Text);
if (!string.IsNullOrEmpty(ColorDropDownList.SelectedValue))
queryString.AppendFormat(" {0}:\"{1}\"", "Color", ColorDropDownList.SelectedValue);
// scope can also be passed on the 's' query string parameter
if (!string.IsNullOrEmpty(ScopeDropDownList.SelectedValue))
queryString.AppendFormat(" {0}:\"{1}\"", "Scope", ScopeDropDownList.SelectedValue);
return queryString.ToString();
}
It simply uses a StringBuilder to assemble a query string as we saw in the above query string syntax. I’ve also attached the code to this post as a starting point for you. Hopefully, you will find it useful. If you are not familiar with how to deploy a user control, use this post.