Rewriting FullTextQuery within CoreResultsWebPart

Recently I found that SharePoint advanced search used query parts like Title like ‘%querystring%’ when dealing with contains operators. When dealing with documents that had long titles this didn’t yield the expected search results and with further testing I found that using CONTAINS(Title,’”querystring”’) gave me all the results I wanted.

Problem was that the advanced search was out-of-the-box and no way to configure this (as far as I know) so I needed a way to rewrite the FullTextQuery that was being generated by SharePoint without too much custom code and changing the behavior of the CoreResultsWebPart.

Enter: Reflection. I love this tool, but it should be used sparingly in large solutions as there is a performance hit.

Anyway, basically what I did was extend the CoreResultsWebPart and override the SetPropertiesOnHiddenObject method. This method initializes a private field within CoreResultsWebPart of the type SearchResultHiddenObject and this class contains the FullTextQuery propery which we want to modify at runtime.

So, here’s the quick and dirty code (should be cleaned up before production use):

private string queryPattern = @"(?<Title>Title[\w\s]+[^%]%(?<Query>[\w\s\d]+[^%]*)%')";

protected override void SetPropertiesOnHiddenObject() { base.SetPropertiesOnHiddenObject(); try { Type t = this.GetType(); FieldInfo hiddenObjectField = t.BaseType.GetField("srho", BindingFlags.NonPublic | BindingFlags.Instance); if (hiddenObjectField != null) { object hiddenObject = hiddenObjectField.GetValue(this); Type hiddenObjectType = hiddenObject.GetType(); PropertyInfo fullTextQuery = hiddenObjectType.GetProperty("FullTextQuery", BindingFlags.Public | BindingFlags.Instance); string query = fullTextQuery.GetValue(hiddenObject, null) as string; if (query != null) { Match m = Regex.Match(query, queryPattern); if (m.Success) { string queryString = m.Groups["Query"].Value; query = Regex.Replace(query, queryPattern, "CONTAINS(Title,'\"$2\"')", RegexOptions.IgnoreCase); fullTextQuery.SetValue(hiddenObject, query, null); } } } } catch (Exception ex) { HttpContext.Current.Response.Write("Error: " + ex); } }

‘As you can see I use a regular expression to match and replace the query, but you can replace this with however you wish to modify the query.

Replace the out-of-the-box CoreResultsWebPart with this webpart and you’ll retain all the normal functionality except you gain a little more power over the actual query that is used. This works perfectly on SharePoint 2007; I haven’t tested it on SharePoint 2010 and it might not be needed there.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: