搜索查询不够准确

dia*_*old 13 php sqlite search

据我所知,我有一个搜索查询,PHP但需要进行一些改进:

  1. 当我搜索"什么是食物"并且我在数据库中有"什么是食物"时,所有结果都包含关键字"什么","是","食物"之一.期望的行为是显示包含确切短语"什么是食物"的结果(第一个)

  2. 只突出显示查询中的最后一个单词,我想突出显示所有单词

期望的行为:正确的答案显示在顶部,无论其在数据库中的位置如何.

我目前的代码是这样的:

if (isset($_GET["mainSearch"]))
{
  $condition = '';
  $mainSearch = SQLite3::escapeString($_GET['mainSearch']);
  $keyword = $_GET['mainSearch'];
  $query = explode(" ", $keyword);
  $perpageview=7;

  if ($_GET["pageno"])
  {
      $page=$_GET["pageno"];
  }
  else
  {
      $page=1;
  }

  $frompage = $page*$perpageview-$perpageview;

  foreach ($query as $text)
  {
      $condition .= "question LIKE '%".SQLite3::escapeString($text)."%' OR answer LIKE '%".SQLite3::escapeString($text)."%' OR ";
  }
  foreach ($query as $text_2)
  {
      $condition_2 .= "bname LIKE '%".SQLite3::escapeString($text_2)."%' OR bankreq LIKE '%".SQLite3::escapeString($text_2)."%' OR ";
  }

  $condition = substr($condition, 0, -4);
  $condition_2 = substr($condition_2, 0, -4);


  $order = " ORDER BY quiz_id DESC ";
  $order_2 = " ORDER BY id DESC ";
  $sql_query = "SELECT * FROM questions WHERE " . $condition . ' '. $order.' LIMIT '.$frompage.','.$perpageview;
  $sql_query_count = "SELECT COUNT(*) as count FROM questions WHERE " . $condition .' '. $order;
  //$mainAnswer = "SELECT * FROM questions WHERE question LIKE '%$mainSearch%' or answer LIKE '%$mainSearch%'";
  $bank_query = "SELECT * FROM banks WHERE " . $condition_2 . ' LIMIT 1';
  $result = $db->query($sql_query);
  $resultCount = $db->querySingle($sql_query_count);
  $bankret = $db->query($bank_query);
  //$mainAnsRet = $db->query($mainAnswer);
  $pagecount = ceil($resultCount/$perpageview);

  if ($resultCount > 0)
  {
  if ($result && $bankret)
  {
      while ($row = $result->fetchArray(SQLITE3_ASSOC))
      {

          $wording = str_replace($text, "<span style='font-weight: bold; color: #1a0dab;'>".$text."</span>", $row['answer']);

           echo '<div class="quesbox_3">
            <div class="questitle">
                <h2>'.$row["question"].'</h2>
            </div>
            <div class="quesanswer">'.$wording.'</div>
        </div>';
      }
      while ($brow = $bankret->fetchArray(SQLITE3_ASSOC))
      {
            $bname = $brow['bname'];
            $bankbrief = $brow['bankbrief'];
            $bankreq = $brow['bankreq'];
            $bankaddress = $brow['bankaddress'];
            $banklogo = $brow['banklogo'];
            $founded = $brow['founded'];
            $owner = $brow['owner'];
            $available = $brow['available'];


           echo '<div class="modulecontent">
            <div class="modulename">
                <div class="mname">'.$bname.'</div>
                <div class="mlogo"><img src="'.$banklogo.'"></div>
            </div>';

            if (strlen($bankreq) > 300)
            {
                $bankcut = substr($bankreq, 0, 300);

                $bankreq = substr($bankcut, 0, strrpos($bankcut, ' ')).'... <a href="bankprofile.php?bname='.$bname.'">Read More</a>';
                echo '<div class="modulebrief">'.$bankreq.'</div>';
            }
            echo '<div class="modulelinks">
                <div class="mfound">Founded: <span>'.$founded.'</span></div>
                <div class="mowned">Ownd By: <span>'.$owner.'</span></div>
            </div>
        </div>';

               // <div class="mavailable">Available for Export Loan: <span>'.$available.'</span></div>
      }
      ?>
      <div class="page_num">
      <?php
      for ($i=1; $i <= $pagecount; $i++) {
         echo '<a href="searchresult.php?mainSearch='.$mainSearch.'&pageno='.$i.'">'.$i.'</a>';
      }
      ?>
      </div>
      <?php
  }
  }
  else
  {
      $session_n = $_SESSION['log_id'];
      $sesdate = date('d/M/Y');
      echo "<div class='searchNone'><p>No results found</p></div>
      <div class='sendSearchQ'>
      <p>Please send us your question.</p>
      <form action='sendquestion.php' method='post' encytype='multipart/form-data'>
      <div class='searchQinputs'>
          <input type='text' name='searchQuestion' id='searchQuestion'placeholder='Whats your question'><br>
          <input type='submit' name='sendQuestion' id='sendQuestion' value='Send'>
          <input type='text' name='user' id='user' value='$session_n' style='display: none'>
          <input type='text' name='qDate' id='qDate' value='$sesdate' style='display: none'>
          <input type='text' name='status' id='status' value='0' style='display: none'>
          </div>
      </form>
      </div>";
  }
}
Run Code Online (Sandbox Code Playgroud)

Ton*_*cas 10

在查询中添加可排序字段

首先,我们需要简化您的问题

您的问题可以视为简单的关键字匹配,其中最重要的结果必须与输入的所有关键字匹配.

搜索:some search text应返回包含任何这些单词的所有结果['some', 'search', 'text'],其中顶部的结果与输入的完全 匹配"some search text".

这意味着您需要创建一个聚合字段,允许根据匹配对结果进行排序.我知道这样做的唯一方法是在没有重构数据和/或代码的情况下使用MySql Case语句.

您的查询已简化

SELECT *
FROM questions
WHERE
    question LIKE '%[word1]%' OR answer LIKE '%[word1]%'
    OR question LIKE '%[word2]%' OR answer LIKE '%[word2]%'
    OR question LIKE '%[word3]%' OR answer LIKE '%[word3]%'
ORDER BY quiz_id DESC
Run Code Online (Sandbox Code Playgroud)

案例[完全匹配]和排序

我们需要构建的是一个看起来有点像这样的查询:

SELECT *,
    (CASE WHEN
            question LIKE '%[full-search-query]%'
            OR answer LIKE '%[full-search-query]%'
        THEN 1 ELSE 0
    END) as fullmatch
FROM questions
WHERE
    question LIKE '%[word1]%' OR answer LIKE '%[word1]%'
    OR question LIKE '%[word2]%' OR answer LIKE '%[word2]%'
    OR question LIKE '%[word3]%' OR answer LIKE '%[word3]%'
ORDER BY fullmatch DESC, quiz_id DESC
Run Code Online (Sandbox Code Playgroud)

调整你的代码

// your initial storage of the full search, before you split it on spaces
$keyword = $_GET['mainSearch'];

. . .

// build our sorting field
$sortFullMatch = "(CASE WHEN question LIKE '%".SQLite3::escapeString($keyword)."%' OR answer LIKE '%".SQLite3::escapeString($keyword)."%' THEN 1 ELSE 0 END) as fullmatch";

. . .

// adjust the query and sort
$order = " ORDER BY fullmatch DESC, quiz_id DESC ";
$sql_query = "SELECT *,". $sortFullMatch ." FROM questions WHERE ".$condition.' '.$order.' LIMIT '.$frompage.','.$perpageview;
Run Code Online (Sandbox Code Playgroud)

这是做什么的?

我们在SELECT语句中添加了一个新字段fulltext.当问题或答案完全包含完整搜索时,此字段将为1,否则为0.然后只需对此字段进行排序.

突出

至于你的突出问题,你只是替换$text在每个单词的循环中设置的问题mainSearch.因此,它只是集合中的最后一个单词.相反,你需要在这里做一个类似的循环.

你的守则

$wording = str_replace($text, "<span style='font-weight: bold; color: #1a0dab;'>".$text."</span>", $row['answer']);
Run Code Online (Sandbox Code Playgroud)

调整

foreach($query as $text) {
    $wording = str_replace($text, "<span style='font-weight: bold; color: #1a0dab;'>".$text."</span>", $row['answer']);
}
Run Code Online (Sandbox Code Playgroud)