0

我正在根据本教程构建一个简单的实时搜索:http: //blog.ninetofive.me/blog/build-a-live-search-with-ajax-php-and-mysql/

对于这样的查询,它可以很好地使用一个词:搜索示例 1

或者对于包含部分单词的查询:搜索示例 2

或者对于在搜索结果中同时出现的两个词或词的一部分的查询:在此处输入图像描述

但是,如果我搜索两个不相邻的单词,则查询失败:在此处输入图像描述

我将如何修改我的查询,以便我可以搜索出现在结果中任何位置的任意数量的关键字?

例如,如果我的数据库有如下记录:The quick brown fox jumps over the lazy dog

quick jumps dog如果我搜索:或dog over不只是quick brownfox jumpsfox等等,我希望返回结果。

如果查询中包含多个单词,然后将我的查询$search_string变成一组关键字以MySQL进行查询,我正在考虑一些类似的事情,但我不知道这是否是最好的方法。

询问:

// Get Search
$search_string = preg_replace("/[^A-Za-z0-9]+[.]/", " ", $_POST['query']);
$search_string = $tutorial_db->real_escape_string($search_string);

// Check Length More Than One Character
if (strlen($search_string) >= 1 && $search_string !== ' ') {

// Build Query
$query = 'SELECT * FROM search WHERE subsection LIKE "%'.$search_string.'%" OR def LIKE "%'.$search_string.'%" OR exception LIKE "%'.$search_string.'%" ORDER BY subsection ASC';

完整代码:

<?php
/************************************************
    The Search PHP File
************************************************/


/************************************************
    MySQL Connect
************************************************/

// Credentials
$dbhost = "localhost";
$dbname = "livesearch";
$dbuser = "live";
$dbpass = "search";

//  Connection
global $tutorial_db;

$tutorial_db = new mysqli();
$tutorial_db->connect($dbhost, $dbuser, $dbpass, $dbname);
$tutorial_db->set_charset("utf8");

//  Check Connection
if ($tutorial_db->connect_errno) {
  printf("Connect failed: %s\n", $tutorial_db->connect_error);
  exit();
}

/************************************************
    Search Functionality
************************************************/

// Define Output HTML Formating
$html = '';
$html .= '<li class="result">';
$html .= '<a target="_blank" href="urlString">';
$html .= '<h2><b> codeString - yearString - chapterString - sectionString - SUBHERE</b></h1>';
$html .= '<h3>defString</h3>';

//try to add exception string
$html .= '</br><h3>exceptionString</h3>';

$html .= '</a>';
$html .= '</li>';

// Get Search
$search_string = preg_replace("/[^A-Za-z0-9]+[.]/", " ", $_POST['query']);
$search_string = $tutorial_db->real_escape_string($search_string);

// Check Length More Than One Character
if (strlen($search_string) >= 1 && $search_string !== ' ') {
  // Build Query
  //$query = 'SELECT * FROM search WHERE function LIKE "%'.$search_string.'%" OR name LIKE "%'.$search_string.'%"';

  $query = 'SELECT * FROM search WHERE subsection LIKE "%'.$search_string.'%" OR def LIKE "%'.$search_string.'%" OR exception LIKE "%'.$search_string.'%" ORDER BY subsection ASC';

  // Do Search
  $result = $tutorial_db->query($query);
  while($results = $result->fetch_array()) {
    $result_array[] = $results;
  }

  // Check If We Have Results
  if (isset($result_array)) {
    foreach ($result_array as $result) {
      // Format Output Strings And Hightlight Matches
      //$display_function = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['function']);
      //$display_name = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['name']);
      //$display_url = 'http://php.net/manual-lookup.php?pattern='.urlencode($result['function']).'&lang=en';

      // Format Output Strings And Hightlight Matches
      //Format code - ex IBC
      $display_code = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['code']);

      //Format year - ex 2012
      $display_year = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['year']);

      //Format Chapter - ex Means Of Egress
      $display_chapter = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['chapter']);

      //Format Section - ex Stairs
      $display_section = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['section']);

      //Format sub Section - ex 1009.4 width
      $display_sub = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['subsection']);

      //$display_subsection = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['subsection']);

      $display_def = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['def']);

      $display_exception = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['exception']);

      $display_url = 'http://php.net/manual-lookup.php?pattern='.urlencode($result['code']).'&lang=en';

      // Insert Name
      $output = str_replace('nameString', $display_name, $html);

      //Insert Code
      $output = str_replace('codeString', $display_code, $output);

      //Insert Year
      $output = str_replace('yearString', $display_year, $output);

      //Insert Chapter
      $output = str_replace('chapterString', $display_chapter, $output);

      // Insert Section
      $output = str_replace('sectionString', $display_section, $output);

      // Insert Sub Section
      $output = str_replace('SUBHERE', $display_sub, $output);

      // Insert Defenition
      $output = str_replace('defString', $display_def, $output);

      // Insert exceptions
      $output = str_replace('exceptionString', $display_exception, $output);

      // Insert URL
      $output = str_replace('urlString', $display_url, $output);

      // Output
      echo($output);
    }
  }else{
    // Format No Results Output
    $output = str_replace('urlString', 'javascript:void(0);', $html);
    $output = str_replace('nameString', '<b>No Results Found.</b>', $output);
    $output = str_replace('functionString', 'Sorry :(', $output);

    // Output
    echo($output);
  }
}

?>
4

3 回答 3

0

正如其他人指出的那样,您需要为LIKE搜索中的每个单词使用条件。

因此,作为解决问题的第一种方法,请像这样拆分您的输入:

$search_string = 'jump lazy dog';
$search_terms = explode(' ', $search_string);
$query = 'SELECT *
    FROM search
    WHERE ';
foreach($search_terms as $term) {
    $query .= '(subsection LIKE "%'.$term.'%" OR def LIKE "%'.$term.'%" OR exception LIKE "%'.$term.'%") AND ';
}
$query = substr($query, 0, -4).'ORDER BY subsection ASC';

echo $query;

这将产生您需要的查询:

SELECT *
FROM search
WHERE (subsection LIKE "%jump%" OR def LIKE "%jump%" OR exception LIKE "%jump%")
    AND (subsection LIKE "%lazy%" OR def LIKE "%lazy%" OR exception LIKE "%lazy%")
    AND (subsection LIKE "%dog%" OR def LIKE "%dog%" OR exception LIKE "%dog%")
ORDER BY subsection ASC

(我添加了换行符和缩进只是为了更容易阅读。)

然而,这里有一个巨大的问题:由于存在 SQL 注入的风险,这是非常不安全的您需要使用准备好的语句来防止这种情况。有关此问题的各种方法,请参阅此帮助页面。

于 2013-11-01T19:17:16.857 回答
0

对 WHERE 语句的 2 个以上参数使用括号。

$query = 'SELECT * FROM search WHERE (subsection LIKE "%'.$search_string.'%" OR def LIKE "%'.$search_string.'%" OR exception LIKE "%'.$search_string.'%") ORDER BY subsection ASC';
于 2013-11-01T17:51:05.180 回答
0
  1. 对于每个单词,都有LIKE %word% OR LIKE %word2%@iamde_coder 建议的 etc 结构
  2. 按照@fred-ii 的建议使用布尔搜索
  3. 使用专门的搜索服务器,根据语言拆分单词,去掉停用词等。例如SOLRsphinx
于 2013-11-01T18:18:44.993 回答