Time for action - searching with different matching modes

  1. Create a PHP script display_results.php in your webroot with the following code:
    <?php
    // Database connection credentials
    $dsn ='mysql:dbname=myblog;host=localhost';
    $user = 'root';
    $pass = '';
    // Instantiate the PDO (PHP 5 specific) class
    try {
    $dbh = new PDO($dsn, $user, $pass);
    } catch (PDOException $e){
    echo'Connection failed: '.$e->getMessage();
    }
    // PDO statement to fetch the post data
    $query = "SELECT p.*, a.name FROM posts AS p " .
    "LEFT JOIN authors AS a ON p.author_id = a.id " .
    "WHERE p.id = :post_id";
    $post_stmt = $dbh->prepare($query);
    // PDO statement to fetch the post's categories
    $query = "SELECT c.name FROM posts_categories AS pc ".
    "LEFT JOIN categories AS c ON pc.category_id = c.id " .
    "WHERE pc.post_id = :post_id";
    $cat_stmt = $dbh->prepare($query);
    // Function to display the results in a nice format
    function display_results($results, $message = null)
    {
    global $post_stmt, $cat_stmt;
    if ($message) {
    print "<h3>$message</h3>";
    }
    if (!isset($results['matches'])) {
    print "No results found<hr />";
    return;
    }
    foreach ($results['matches'] as $result) {
    // Get the data for this document (post) from db
    $post_stmt->bindParam(':post_id',
    $result['id'],
    PDO::PARAM_INT);
    $post_stmt->execute();
    $post = $post_stmt->fetch(PDO::FETCH_ASSOC);
    // Get the categories of this post
    $cat_stmt->bindParam(':post_id',
    $result['id'],
    PDO::PARAM_INT);
    $cat_stmt->execute();
    $categories = $cat_stmt->fetchAll(PDO::FETCH_ASSOC);
    // Output title, author and categories
    print "Id: {$posmt['id']}<br />" .
    "Title: {$post['title']}<br />" .
    "Author: {$post['name']}";
    $cats = array();
    foreach ($categories as $category) {
    $cats[] = $category['name'];
    }
    if (count($cats)) {
    print "<br />Categories: " . implode(', ', $cats);
    }
    print "<hr />";
    }
    }
    
  2. Create a PHP script search_matching_modes.php in your webroot with the following code:
    <?php
    // Include the api class
    Require('sphinxapi.php'),
    // Include the file which contains the function to display results
    require_once('display_results.php'),
    $client = new SphinxClient();
    // Set search options
    $client->SetServer('localhost', 9312);
    $client->SetConnectTimeout(1);
    $client->SetArrayResult(true);
    // SPH_MATCH_ALL mode will be used by default
    // and we need not set it explicitly
    display_results(
    $client->Query('php'),
    '"php" with SPH_MATCH_ALL'),
    display_results(
    $client->Query('programming'),
    '"programming" with SPH_MATCH_ALL'),
    display_results(
    $client->Query('php programming'),
    '"php programming" with SPH_MATCH_ALL'),
    // Set the mode to SPH_MATCH_ANY
    $client->SetMatchMode(SPH_MATCH_ANY);
    display_results(
    $client->Query('php programming'),
    '"php programming" with SPH_MATCH_ANY'),
    // Set the mode to SPH_MATCH_PHRASE
    $client->SetMatchMode(SPH_MATCH_PHRASE);
    display_results(
    $client->Query('php programming'),
    '"php programming" with SPH_MATCH_PHRASE'),
    display_results(
    $client->Query('scripting language'),
    '"scripting language" with SPH_MATCH_PHRASE'),
    // Set the mode to SPH_MATCH_FULLSCAN
    $client->SetMatchMode(SPH_MATCH_FULLSCAN);
    display_results(
    $client->Query('php'),
    '"php programming" with SPH_MATCH_FULLSCAN'),
    
  3. Execute search_matching_modes.php in a browser (http://localhost/sphinx/search_matching_modes.php).

What just happened?

The first thing we did was created a script, display_results.php, which connects to the database and gathers additional information on related posts. This script has a function, display_results() that outputs the Sphinx results returned in a nice format. The code is pretty much self explanatory.

Next, we created the PHP script that actually performs the search. We used the following matching modes and queried using different search terms:

  • SPH_MATCH_ALL (Default mode which doesn't need to be explicitly set)
  • SPH_MATCH_ANY
  • SPH_MATCH_PHRASE
  • SPH_MATCH_FULLSCAN

Let's see what the output of each query was and try to understand it:

display_results(
$client->Query('php'),
'"php" with SPH_MATCH_ALL'),
display_results(
$client->Query('programming'),
'"programming" with SPH_MATCH_ALL'),

The output for these two queries can be seen in the following screenshot:

What just happened?

The first two queries returned all posts containing the words "php" and "programming" respectively. We got posts with id 2 and 5 for "php", and 5 and 8 for "programming".

The third query was for posts containing both words, that is "php programming", and it returned the following result:

What just happened?

This time we only got posts with id 5, as this was the only post containing both the words of the phrase "php programming".

We used SPH_MATCH_ANY to search for any words of the search phrase:

// Set the mode to SPH_MATCH_ANY
$client->SetMatchMode(SPH_MATCH_ANY);
display_results(
$client->Query('php programming'),
'"php programming" with SPH_MATCH_ANY'),

The function call returns the following output (results):

What just happened?

As expected, we got posts with ids 5,2, and 8. All these posts contain either "php" or "programming" or both.

Next, we tried our hand at SPH_MATCH_PHRASE, which returns only those records that match the search phrase exactly, that is, all words in the search phrase appear in the same order and consecutively in the index:

// Set the mode to SPH_MATCH_PHRASE
$client->SetMatchMode(SPH_MATCH_PHRASE);
display_results(
$client->Query('php programming'),
'"php programming" with SPH_MATCH_PHRASE'),
display_results(
$client->Query('scripting language'),
'"scripting language" with SPH_MATCH_PHRASE'),

The previous two function calls return the following results:

What just happened?

The query"php programming" didn't return any results because there were no posts that match that exact phrase. However, a post with id 2 matched the next query: "scripting language".

The last matching mode we used was SPH_MATCH_FULLSCAN. When this mode is used the search phrase is completely ignored, (in our case "php" was ignored) and Sphinx returns all records from the index:

// Set the mode to SPH_MATCH_FULLSCAN
$client->SetMatchMode(SPH_MATCH_FULLSCAN);
display_results(
$client->Query('php'),
'"php programming" with SPH_MATCH_FULLSCAN'),

The function call returns the following result (for brevity only a part of the output is shown in the following image):

What just happened?

Note

SPH_MATCH_FULLSCAN mode is automatically used if empty string is passed to the SphinxClient::Query() method.

SPH_MATCH_FULLSCAN matches all indexed documents, but the search query still applies all the filters when sorting and grouping. However, the search query will not perform any full-text searching. This is particularly useful in cases where we only want to apply filters and don't want to perform any full-text matching (For example, filtering all blog posts by categories).

Boolean query syntax

Boolean mode queries allow expressions to make use of a complex set of Boolean rules to refine their searches. These queries are very powerful when applied to full-text searching. When using Boolean query syntax, certain characters have special meaning, as given in the following list:

  • &: Explicit AND operator
  • |: OR operator
  • -: NOT operator
  • !: NOT operator (alternate)
  • (): Grouping

Let's try to understand each of these operators using an example.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset