Greg's Blog

helping me remember what I figure out

Adding Search Functionality to Your Site: Real Basic (Part 1)

| Comments

If you were to compare visiting a web site to visiting a store, you generally adopt to approaches to finding what you are after in the real world. The first is to browse the store until you find what you are after, going through all the aisles. Alternatively you could simply ask somebody. Visiting a web site isn’t unlike entering a store, generally you can adopt those two approaches as well. Browsing the site, by following the navigational links provided until you find what you are after. Or you could ask somebody… Well not really, but the search option found on most web sites, I guess is the on-line equivalent. The merits of many search engines and the results they return is questionable. Having said that have you been to K-mart recently and asked someone there for help? They are more likely to send you on an entire tour of the store without ever finding what you are after or even more annoying just blink in your direction with a puzzled look… But I digress…

Building an intelligent search engine is a complex undertaking and one that isn’t taken on lightly. So in the following series of articles I shall endeavour to figure out what makes up a good search engine, starting with a real basic search functionality and then gradually trying to improve on it. This will research will not only focus on the technical and coding aspects, but also focus on the presentation or usability side of things. So let’s get cracking. Some prerequisites, well the search will be built using PHP and MySQL, so make sure you have these running and a set of tables with content in them to run your search queries against.

In the first instance you’ll need to submit some information to a search engine and hence you’ll need a form. Keep this form as simple as possible, you don’t want to baffle your user with options so generally an input field with a search button is good enough, however if you really feel that allowing the user to narrow down his search from the outset is a good thing by say selecting a \n option from a drop down menu (for say a book) then try and lay it out so that it forms a sentence (i.e. ‘search _____ for ________’ or using our book example: ‘search books for Dostoevski’). And below is a sample form:

<form method=”post” action=”search/” name=”frm_search” id=”frm_search” enctype=”application/x-www-form-urlencoded”>
<span id=”elField0” class=”alert”></span><img src=”images/s.gif” width=”15” height=”1” alt=”spacer” border=”0” /><br />
<input type=”Text” name=”r_search” id=”r_search” value=”” size=”15” class=”body” />
<input type=”Submit” name=”btn_submit” id=”btn_submit” value=”search” class=”headeru” />
</form>

This form will submit a form field labelled r_search to the index page in the search folder on your web server. I would recommend that you validate the user input before submitting the form by using a javascript, just so to stop empty form submissions for example.

Now onto the interesting part, the script that gets executed searches for the requested information and displays the result. The idea here is that we are submitting a string to a database filled to the brim with useful content and we want to retrieve the content that contains the submitted string. What we will be doing in the following is making use of the SQL operator LIKE to find out content.

The Code:
<?php
/* include your own database connection info here /*
if (isset($r_search) && ($r_search <> “”)) {
  $sql2 = “SELECT content_id, teaser, title, content from article where title like ‘%”.$r_search.”%’ OR teaser like ‘%”.$r_search.”%’ OR content like ‘%”.$r_search.”%’”;

  $result2 = mysql_query($sql2);
  if (!$result2)
    $msg .= “Query: “.$sql2.” failed”;

  $total2 = mysql_numrows($result2);

  $page_content .= “<p class="bodyb">Your search for "<span class="header">”.$r_search.”</span>" returned “.$total2.” results.<hr class="body" /></p>”;

  if ($total2 <> 0) {
    $counter = 1;
    while($r2 = mysql_fetch_array($result2)) {
      $page_content .= “<div><span class="bodyb">”.$counter.”.</span><img src="”.$http.”images/s.gif" width="10" height="1" alt="spacer" border="0" /><a href="”.$http.”article/article.php?id=”.$r2[0].”" class="normb_s">”.stripslashes($r2[2]).”</a><br />”.stripslashes($r2[1]).”<br /><img src="”.$http.”images/s.gif" width="1" height="15" alt="spacer" border="0" /></div>”;
      $counter++;
    }
  } else {
    $page_content .= “<div>&t;span class="header">Sorry</span><br />Sorry your search for “.$r_search.” returned 0 results.</div>”;
  }
} else {
  $page_content .= “<div>&t;span class="header">Sorry</span><br />Sorry before searching for information please make sure that the search field has been completed.</div>”;
}
?>

So what’s going on here? Well for starters we check to see if $r_search has been submitted and that it doesn’t contain a blank value. Ideally you should have validated the input before being submitted to the server, but if users have javascript disabled then your client side validation counts for nothing and hence you should also validate server side.

Next I build up my query using the LIKE operator. I decided to search three fields in my database where relevant information may be stored, these are the content title, teaser and body. Then the query gets executed. If the results are greater than 0 ($total2) then I build up a result list. For informational purposes I instruct the user of the number of results his search has generated and then proceed to loop over the result set to generate a list with a link to the content that returned a result. The result may well look something like this:

Your search for ”the” returned 58 results.


1.spacerJavaScript: Automatic submit using onChange
Ever wanted to know how to submit a form after changing a drop down field? Read on…
spacer
2.spacerConfiguring Cold Fusion and MySQL
Some helpful hints on configuring CF 4.5.1 to use MySQL as the dB server…
spacer

And that concludes my first installment on searching. This isn’t a very intelligent search mechanism and only does the most basic searching and even that is limited. For example the search I used in my example above was for the word “the” and it returned only 58 results. Now I am pretty sure that there are more than 58 instances of the word “the” stored in my database. And do we really want to allow searches for words like “the, and, to, etc…”. Regardless of these search options, certain searches may well return 1000 of instances, do we really want to display them all on one page? So just to wet your appetite in the next installment we shall be looking at making a previous, next functionality to step through large result sets easily. Once we have that under our belt we’ll look at improving the searching of the database.