Recently we decided to add a searching feature for the different sites we run on gaiaware.net: main site, blogs, forum, tracker, docs and API reference. We wanted to be able to search each site separately and still have all the results presented in a intuitive way. And of course, it should be built using Gaia Ajax, so it could be quickly developed (our customers say they increase the productivity by 30-50% on the ASP.NET platform when using Gaia Ajax) and give a responsive and ajaxified user experience.
We have purchased a Google Site Search subscription so we don't have to reinvent the wheel again and make our own site spider. The Google Site Search gives us the search results in XML, and we can parse and present them in any way we would like.
The challenge: multiple search sources with ASP.NET
Since we wanted to present the results from each sub site in separate sections, we needed to overcome some limitations of what Google Site Search gives us. E.g. you can return max 20 results per search. Since we wanted to separate the results in each sub domain (e.g. forum.gaiaware.net) we needed to use the useful "site:" parameter in a Google query. That meant that we needed to fire off 5-6 Google searches for each search we executed on our own page. Our immediate concern was how long time it would take to perform so many Google searches, return them, parse them and present them on our ASP.NET page.
The solution: Page.RegisterAsyncTask
We needed an asynchronous way of doing this. What would be the easiest way? After some consideration and reading on Internet we decided to implement the Page.RegisterAsyncTask method. Scott Allen has done some performance testing on this method as well.
How we created it
1. Created a helper class to store information about each section to be searched
private static List<SearchSection> SearchSections
List<SearchSection> sections = new List<SearchSection>();
sections.Add(CreateSearchSection("forum.gaiaware.net", "Forum", SearchSectionEnum.Forum));
sections.Add(CreateSearchSection("docs.gaiaware.net", "docs.gaiaware.net/api", "Docs", SearchSectionEnum.Docs));
sections.Add(CreateSearchSection("docs.gaiaware.net/api", "Api Docs", SearchSectionEnum.ApiDocs));
sections.Add(CreateSearchSection("tracker.gaiaware.net", "Tracker", SearchSectionEnum.Tracker));
sections.Add(CreateSearchSection("blogs.gaiaware.net", "Blogs", SearchSectionEnum.Blogs));
sections.Add(CreateSearchSection("samples.gaiaware.net", "Samples", SearchSectionEnum.Samples));
2. Iterate through the sections and fire off the async Google search
foreach (SearchSection searchControlHelper in SearchSections)
Page.RegisterAsyncTask(CreateAsyncGoogleSearch(searchControlHelper, _numberOfSearchResults, 0));
Each task is implemented like this:
private PageAsyncTask CreateAsyncGoogleSearch(SearchSection searchSection, int num, int start)
return new PageAsyncTask(
delegate(object sender, EventArgs e, AsyncCallback cb, object state)
//create query path string to use in search
string fullQueryPath = SearchSection.CreateSearchUri(
searchSection.GetQueryAndSiteParameter(GoogleSearchParameter, Page), num, start);
return GetResponseForSearch(cb, fullQueryPath);
//TODO implement timeouthandler
}, null, true);
3. Each result is added to Gaia Accordion
The Gaia Accordion is a container control that takes Gaia ExtendedPanels as child controls. To display the search results, we have inherited from a Gaia ExtendedPanel and added specific logic like Gaia LinkButtons for navigation a Gaia Label to display the returned HTML results. The ExtendedPanelResult also stor
es which page the user has navigated to in a property called Start, which is stored in a ViewState property.
Yes, we were concerned about performance for running 6 searches concurrently: For the first initial search it takes only around 250ms in this environment. Below is a screenshot when doing first initial search and then navigating the search results. I would say that around 250-300 ms is acceptable!
Want to do the same?
The code above will be a part of the samples in our upcoming Gaia Ajax 3.6 release. But, already now you can download the code from our nightly build and public SVN source code access. The easiest access to the source is to download the trial version of our nightly build. The name of the sample is Ajax-AsyncGoogleSearch.aspx and is written in C#.
Gaia Ajax is a dual licensed product, meaning if you build commercial closed source, you will need to obtain a commercial license to use the sample above. If you are building Open Source web applictations, you are free to use our GPL version, which also comes as a nightly build.