Customizing Sharepoint Search - overriding search results webpart
Some times ago, I developed custom search solution in SharePoint 2007 enviroment.
I implemented search using Search URL Syntax
I needed special custom search webpart with multiple additional search criteria related to custom properties. additionally I implemented custom result webpart
Introduction
In this article i describe, how to create additional filter to search results by overriding
"core search result" webpart.
Searching using URL syntax query has limited functionality (searching by scope or keyword).
It is not posibile to compare dates or number, (like greather then 01.01.2008 or less then 15).
why not just use full text search engine? Because using URL syntaxt query give more flexibilty! You can easly redirect your search results to other pages/webparts!
Using aproach described in this article, it is posible to perfom compare operation on searched columns with date or number values.The way to do this, it is filtering already returned search results in search results webpart.
Implementation
1) Override CoreResultsWebPart webpart
namespace SearchWebParts
{
[Guid("85DF3779-8E2C-49c9-8A83-828DC4FACE03")]
[Guid("85DF3779-8E2C-49c9-8A83-828DC4FACE03")]
public class EasyAdvancedSearchResults : Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart
{
2) where to modify search results???
2) where to modify search results???
Search results are stored in xmlResponseDoc member variable. Good place to modify it is in protected
ModifyXsltArgumentList(Microsoft.SharePoint.WebPartPages.ArgumentClassWrapper argList) method.
#region Overrides
protected override void ModifyXsltArgumentList(Microsoft.SharePoint.WebPartPages.ArgumentClassWrapper argList)
{
base.ModifyXsltArgumentList(argList);
//here starts custom filtering of the search results
FilterSearchResultsByCreateDate();
} #endregion Overrides
3) Get filter parameters
In this example i need to filter searched documents with creation date.
User can select the scope of creation date with start date and end date parameters on the custom search webpart. This parameters are then send with url query. For example:
http://testdomain/sites/test/erweitertesuche.aspx?k=search&fromdate=06.04.2009+00%3a00%3a00&todate=30.04.2009+00%3a00%3a00&s=Alle+ERGO+Dokumente&start=1
Get this values from URL in our custom result webpart
System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.CurrentCulture;
//filter when one of the date parameters is present 'fromdate' or 'todate'
if (this.Context.Request["todate"] != null || this.Context.Request["fromdate"] != null)
{
//try parse 'to date' parameter
if (this.Context.Request["todate"] != null)
{
DateTime.TryParse(this.Context.Request["todate"], provider, System.Globalization.DateTimeStyles.None, out toDate);
}
//try parse 'from date' parameter
if (this.Context.Request["fromdate"]!=null)
{
DateTime.TryParse(this.Context.Request["fromdate"], provider, System.Globalization.DateTimeStyles.None, out fromDate);
}
User can select the scope of creation date with start date and end date parameters on the custom search webpart. This parameters are then send with url query. For example:
http://testdomain/sites/test/erweitertesuche.aspx?k=search&fromdate=06.04.2009+00%3a00%3a00&todate=30.04.2009+00%3a00%3a00&s=Alle+ERGO+Dokumente&start=1
Get this values from URL in our custom result webpart
System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.CurrentCulture;
//filter when one of the date parameters is present 'fromdate' or 'todate'
if (this.Context.Request["todate"] != null || this.Context.Request["fromdate"] != null)
{
//try parse 'to date' parameter
if (this.Context.Request["todate"] != null)
{
DateTime.TryParse(this.Context.Request["todate"], provider, System.Globalization.DateTimeStyles.None, out toDate);
}
//try parse 'from date' parameter
if (this.Context.Request["fromdate"]!=null)
{
DateTime.TryParse(this.Context.Request["fromdate"], provider, System.Globalization.DateTimeStyles.None, out fromDate);
}
4) Filter search results
Filter results by creation date with start date and end date parameters.
You have results in
protected XmlDocument xmlResponseDoc;
Modfiy xml results the way you want. I do this using LINQ query, fast and easy.
//get original xml with search results XElement root = XElement.Parse(xmlResponseDoc.InnerXml);
//LINQ query, results are filtered by 'from date' and 'to date'
IEnumerable<XElement> searchResults =
from el in root.Elements()
where DateTime.Parse((string)el.Element("write").Value, provider) > fromDate &&
DateTime.Parse((string)el.Element("write").Value, provider) < toDate
select el;
5) Set filtered xml as a new search results value
//set filtered result as a new search result
root.ReplaceNodes(searchResults);
xmlResponseDoc.InnerXml = root.ToString();
//get original xml with search results XElement root = XElement.Parse(xmlResponseDoc.InnerXml);
//LINQ query, results are filtered by 'from date' and 'to date'
IEnumerable<XElement> searchResults =
from el in root.Elements()
where DateTime.Parse((string)el.Element("write").Value, provider) > fromDate &&
DateTime.Parse((string)el.Element("write").Value, provider) < toDate
select el;
5) Set filtered xml as a new search results value
//set filtered result as a new search result
root.ReplaceNodes(searchResults);
xmlResponseDoc.InnerXml = root.ToString();
Below complete method listing
#region Private methods
///
/// Filter original results xml by create date.
/// Filter parameters are requested from context.
///
private void FilterSearchResultsByCreateDate()
{
//set initial values for parameters
DateTime fromDate = DateTime.MinValue;
DateTime toDate = DateTime.MaxValue;
System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.CurrentCulture;
//filter when one of the date parameters is present 'fromdate' or 'todate'
if (this.Context.Request["todate"] != null || this.Context.Request["fromdate"] != null)
{
//try parse 'to date' parameter
if (this.Context.Request["todate"] != null)
{
DateTime.TryParse(this.Context.Request["todate"], provider, System.Globalization.DateTimeStyles.None, out toDate);
}
//try parse 'from date' parameter
if (this.Context.Request["fromdate"]!=null)
{
DateTime.TryParse(this.Context.Request["fromdate"], provider, System.Globalization.DateTimeStyles.None, out fromDate);
}
//get original xml with search results
XElement root = XElement.Parse(xmlResponseDoc.InnerXml);
//LINQ query, results are filtered by 'from date' and 'to date'
IEnumerable searchResults =
from el in root.Elements()
where DateTime.Parse((string)el.Element("write").Value, provider) > fromDate &&
DateTime.Parse((string)el.Element("write").Value, provider) < toDate
select el;
//set filtered result as a new search result
root.ReplaceNodes(searchResults);
xmlResponseDoc.InnerXml = root.ToString();
}
}
#endregion Private methods
Thanks a lot dude..You save my time
ReplyDeleteGiven so much information in it. its very useful .Thanks for your valuable information.
ReplyDeletedot net training center in chennai |
best dot net training in chennai