Database Articles
  Home arrow Database Articles arrow Page 26 - Creating a Search Application
Codewalker Forums 
  Tutorials  
Database Articles  
Miscellaneous  
Navigation Usability  
PEAR Articles  
Programming Basics  
Server Administration  
XML Tutorials  
  Reviews  
Database Book Reviews  
Linux Book Reviews  
Miscellaneous Reviews  
PHP Book Reviews  
PHP Software Reviews  
Server Admin Reviews  
SQL Tool Reviews  
  Code Gallery  
Content Management Code  
Contest Code  
Counters Code  
Database Code  
Date Time Code  
Discussion Board Code  
Email Code  
File Manipulation Code  
GUI Code  
Link Farm Code  
Miscellaneous Code  
Search Code  
Site Navigation Code  
User Management Code  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Download TestComplete 
Forums Sitemap 
Weekly Newsletter 
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
DATABASE ARTICLES

Creating a Search Application
By: Matt Wade
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 3 stars3 stars3 stars3 stars3 stars / 14
    2003-07-15

    Table of Contents:
  • Creating a Search Application
  • Database Usage
  • Creating a Search Application
  • Searching
  • Conclusion

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Creating a Search Application -


    (Page 26 of 29 )

    Now it is time to develop a way to do fuzzy searching. What we want to do is find words that are similar to the ones the user searched for and didn't exist in our keyword list. To make this happen, we will use the similar_text() function of PHP.

    The similar_text() function provides very good results but at the price of performance. Running a very large amount of keywords through the similar_text() function could create a sluggish application. One alternative is the levenshtein() function which is much better performance wise when compared to the similar_text() function. The drawback is that levenshtein() produces results that are not quite as accurate as similar_text().

    The similar_text() function takes three parameters. The first and second are the words to compare, and the third is a variable to store the percentage of how similar they are. A similarity of 100% would be exactly the same, and it goes down from there. The levenshtein() function works in a very similar fashion to similar_text(). The one difference is that it assigns a cost value to the third parameter rather than a percentage. In this case, a lower number means a closer match. If you choose to use the levenshtein() function, keep this in mind when sorting the array later in the script. You will need to sort it in normal order rather than in reverse.

    Now that we have covered a little bit of theory behind this function, let's take a look at how it will actually work.

  • Select all keywords from the keywords table that start with the same character as one of our search terms.
  • Build a list of matches for each search term
  • Merge the search term matches
  • Build query
  • Run query and display results Select all keywords from table

    The first thing we need to do is query the database and select all the keywords from the keywords table that start with the same character as one of our search terms. To only match against the first letter of the keyword, we will utilize the LEFT function of MySQL in our query. We will also use the DISTINCT SQL function to only retrieve unique keywords. The query will be built dynamically as we have done several other times. We will take the results from this query and store them in an array.

    <?php
    $match 
    "LEFT(keyword,1) in ('"
           
    substr($this-&gt;_searchterms[0], 01) . "'";
    for (
    $i 1$i &lt$this-&gt;_numterms$i++) {
        
    $match .= ", '" substr($this-&gt;_searchterms[$i], 01) . "'";
    }
    $match .= ")";
    $query "SELECT DISTINCT(keyword) FROM keywords WHERE $match";
    $keywords $this-&gt;_db-&gt;fetch($query);
    ?>

    Build a list of matches for each search term

    Now, we need to take each search term and each keyword and let the similar_text() function determine how alike they are. We will use foreach loops to iterate through each search term and keyword. Before we begin, we will use the reset() function to return the array pointer back to the first element of the $_searchterms class variable.

    Once we determine how similar each keyword is in relation to a search term, we use the array_walk() function to call the _highpercent() function for each element to remove any keywords that are found to be less than 60% similar.

    <?php
    reset
    ($this-&gt;_searchterms);
    foreach (
    $this-&gt;_searchterms as $term) {
        foreach (
    $keywords as $keyword) {
            
    $word $keyword['keyword'];
            
    similar_text($term$word$matches["$term"]["$word"]);
        }
        
    array_walk ($matches["$term"],
                    array(
    $this'_highpercent'),
                    &
    amp;$matches["$term"]);
    }
    ?>

    Merge the search term matches

    At this point, we will have an associative array named $matches that has as an element for each search term with that search term as the key. Each of these elements is also an associative array. What we now need to do is to combine each of these inner associative arrays into one. To do this we will need to use the array_merge() function. Because we don't know how many search terms we are dealing with, we will need to also use the eval() function to accomplish this task.

    The eval() function takes a string and evaluates it as PHP code. What we are going to do is build a string that contains a PHP statement, much as we did for the queries earlier. Once we build the string, we will pass it to the eval() function and let it evaluate it. Upon evaluation, the inner arrays will be merged and stored in the $merged variable.

    If we only have one search term, we don't need to go through all this so we will just assign the contents of the only inner array to the variable $merged. Once we have the data in the $merged array we will sort it in reverse order, and maintain key relationships, with the arsort() function. Then we will extract the names of keys, as they are the similar keywords, and store them in an array called $search.

    <?php
    if($this-&gt;_numterms &gt1) {
        
    $merge '$merged = array_merge($matches["'
               
    $this-&gt;_searchterms[0] . '"]';
        for (
    $i 1$i &lt$this-&gt;_numterms$i++) {
            
    $merge .= ', $matches["'
                    
    $this-&gt;_searchterms[$i] . '"]';
        }
        
    $merge .= ');';
        eval (
    $merge);
    } else {
        
    $merged $matches[$this-&gt;_searchterms[0]];
    }
    arsort($merged);
    $search array_keys($merged);
    ?>

    Build query

    Now, we have a list of similar keywords that exist in our keywords table. We now must run a query to determine what URLs they are associated with and with what frequency they occur. Before we run the query, however, we will escape any character in the $search array by passing it through the array_walk() function and specifying the function _slashit() that will call the addslashes() function for each array element.

    Then, we will build the query as we have in the past. If we have rows in the result set, we will return them. Otherwise we will return FALSE.

    <?php
    array_walk
    ($search, array($this'_slashit'));
    $match "keywords.keyword in ('"
           
    $search[0] . "'";
    $numwords count ($search);
    for (
    $i 1$i &lt$numwords$i++) {
        
    $match .= ", '" $search[$i] . "'";
    }
    $match .= ")";
    $query "SELECT urls.url, keywords.keyword, count(*) as counter "
           
    "FROM urls, keywords "
           
    "WHERE $match "
           
    "AND keywords.url_id = urls.id "
           
    "GROUP BY keywords.url_id, keywords.keyword "
           
    "ORDER BY counter DESC";
    $result $this-&gt;_db-&gt;fetch($query);
    if (
    count($result) &gt0)
        
    $return $result;
    else
        
    $return FALSE;

    return 
    $return;
    ?>

    More Database Articles Articles
    More By Matt Wade


       · 
       · I've copy and paste the five files regarded in this tutorial, and created the db,...
       · Hello,


    'id' INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,

    I'm...
       · THANKS - MATTVery clear explained tutorial.Wonderful search, I am...
       · My phpadmin had no issues with the table creation, but can't get the harvest script...
       · It's an ok search tutorial, but too many errors.[QUOTE]Warning: array_walk()...
       · Where to post for help on this tutorial?CheersWest
       · great tutorial and very inspiring column in your conclusion.
     

  • DATABASE ARTICLES ARTICLES

    - More on Query Optimization for Oracle Databa...
    - Query Optimization in Oracle
    - Clusters and Other Data Structures for Oracle
    - Using Indexes with an Oracle Database
    - The Basics of Data Structures in Oracle
    - Oracle Data Structures
    - Best Practices for PL/SQL Variables
    - What`s Code Without Variables?
    - Clauses, Sorting, and SQL Queries
    - The From Clause and SQL Queries
    - Query Primer
    - Full Text Searches and Strings
    - Searching with Strings
    - Pattern Matching with Strings
    - Working with Cases of Strings





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 2 Hosted by Hostway
    Stay green...Green IT