Tuesday, March 3, 2009

Front End Search for Norfolk AIR

So the most often asked question I have received so far is how did we handle the search function that is embedded into Norfolk AIR. Being in the GIS development biz it has been something that was always on the radar but just never had the right technology to pull of. Ah and in strolled Ajax





This little beauty is probably the most significant part of the website. Simple, straightforward, so easy anyone can use it. Just start typing and we will try and find it for you.




How was it built?

The search box is actually just a simple asp.net textbox with an ajax autocomplete extender, a textboxwatermark extender and and a hiddenField control all wrapped into one big user control called SearchAssist.




Tied to the search AutoCompleteExtender is a web service that we use to filter the results to the text box (as well as a service other application searchs).

So it goes like this. As the user types the autocomplete extender is listening for the 3rd keystroke. Once the 3rd keystroke is complete the system accesses the webservice to try and retrieve the qualifying values. If it finds some it will return a maximum of 10 records that the user can select from. Pretty simple!

Yes and No

The pretty yes. The simple no.

Behind the scenes we have 3 different sql databases that this search pulls from. (master address, gis (gpins) and real estate (account number)). Actually we are getting ready to add a 4th common place name. Anyway, so as the user is searching the web services is trying to locate like values from 3 different database and present them back to the user...err.. quickly. The quickly part is the key. How do you quickly query 3 database (minimum of 100,000 records each) as fast as the user can type? yeh. The answer is you don't. To overcome the latency problem we actually front ended the queries with a bunch of logic to try and determine if we can narrow down the search before querying the server. Things like if the 1st character isn't a number then I know I don't have to search the address database. If I know I have 5 numbers in a row I don't look for a house number it is probably a gpin or account.





Although a big pain to come up with this was a lifesaver in terms of speed. As the project has progressed I have been able to refine this logic more and more so the query is usually just to one database. Oh yeah did I mention the indexing?

The next big hurdle was know that the user has found a value that they were looking for how does the system know which database that it came from. Don't want to perform all those searches again do I?


Ajax's autocomplete extender actually has a nice feature that I didn't find a lot of documentation on but was able to implement in that you can not only set the returned item name but you can also tie a value to it. This worked out nice as we were able to not only return the search values but also the type(which database they came from)


items.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(dt.Rows.Item(i).Item(displayField).ToString, searchType))

Once the user selects an item from the list we run a little bit of javascript code embedded in the user control(OnClientItemSelected) that will place the database type to a hidden value (thats what the hidden field on the control is for) on the form and presto. We know have the value the user was looking for as well as what database it came from all accessible on the server.


//function SearchSelect( source, eventArgs )
//{
//alert( " Key : "+ eventArgs.get_text() +" Value : "+eventArgs.get_value());
//typeSearch = $get("<%=typeSearch.ClientID %>");
//typeSearch.value = eventArgs.get_value();
//}

That is it. How we were able to produce a really quick, easy to user interface that allows you to search our entire system. The search is so fast that I haven't had anyone be able to out type it yet.

cj



No comments: