【问题标题】:Multiple keywords search多关键词搜索
【发布时间】:2014-12-06 23:43:43
【问题描述】:

在我的网站中添加搜索时遇到问题。我想不出办法来完成它。

我有一张如下表:

TABLE A

id     text
1       Hello there whats up. I'm trying to code.
2       there need to be this code

现在我想使用 关键字 = 你好 代码

结果应该为我提供这两行,因为这两行都包含关键字的某些部分,如下所示:

id      text
1       **Hello** there whats up. I'm trying to **code**
2       there need to be this **code**

结果还应提供首先匹配的最大关键字数的行。

我尝试这样做,但它只提供了一些我想要的结果。

<?php
   $keyword = 'hello code';
   $exloded = explode(' ', $keyword);
   foreach($exploded as value):
      $sth = $db->query("SELECT * FROM A WHERE `text` LIKE :value");
      $sth->execute(array(':value' => '%'.$value.'%'));
      $rows = $sth->fetchAll();
   endforeach;

   echo $rows;
?>

更新

我只是做了这个,对我来说效果很好。但我想知道这是否是完成工作的正确方法。

$keyword = hello code;
$query ="SELECT *, MATCH(`page_content`) AGAINST('$keyword' IN BOOLEAN MODE) AS score      FROM super_pages WHERE MATCH(`page_content`) AGAINST('$keyword' IN BOOLEAN     MODE) ORDER BY score DESC";
$sth = $this->db->query($query);
$result = $sth->fetchAll();

【问题讨论】:

  • 您考虑过 FULLTEXT 列吗?
  • 我尝试了全文搜索但遇到了麻烦所以尝试了这个@Jack

标签: php mysql


【解决方案1】:

$rows 将在您的表中包含您的关键字 code 匹配的数据,您可以重写代码以匹配两个关键字为

$keyword = 'hello code';
$exloded = explode(' ', $keyword);
$query = 'SELECT * FROM A ';
$i = 0;
$params = array();
foreach ($exploded as $value):
    if ($i == 0) {
        $query .= ' WHERE `text` LIKE :value_'.$i;
    } else {
        $query .= ' OR `text` LIKE :value_'.$i;
    }
    $params[':value_'.$i] = '%'.$value .'%';
    $i++;
endforeach;
$sth = $db->query($query);
$sth->execute($params);
$rows = $sth->fetchAll();
echo '<pre>';print_r($rows);echo '</pre>';

在循环中构建您的查询(通过您提供的关键字)并在查询中分配唯一的占位符以匹配所有值

编辑全文搜索

使用全文搜索,您可以将完全相同的短语与提供的关键字匹配,为了使用全文搜索,您需要FULLTEXT 类型的索引。

ALTER TABLE `A` ADD FULLTEXT INDEX `fulltextindex` (`text`); 

查询会是这样的

$keyword = 'hello code';
$exloded = explode(' ', $keyword);
$where = '';
$i = 0;
$select = array();
$params = array();

foreach ($exploded as $value):
    $select[]= ' MATCH(`text`) AGAINST(:value_'.$i.' IN BOOLEAN MODE) ';
    if ($i == 0) {
        $where  .= ' WHERE MATCH(`text`) AGAINST(:value_'.$i.' IN BOOLEAN MODE)';
    } else {
        $where  .= ' OR MATCH(`text`) AGAINST(:value_'.$i.' IN BOOLEAN MODE)';
    }
    $params[':value_'.$i] =  $value ;
    $i++;
endforeach;

$query ='SELECT *,'. implode( ' + ',$select).' AS score FROM A '.$where.' ORDER BY score DESC';
$sth = $db->query($query);
$sth->execute($params);
$rows = $sth->fetchAll();
echo '<pre>';print_r($rows);echo '</pre>';

上面的代码会产生类似的查询

SELECT *,
MATCH(`text`) AGAINST('hello' IN BOOLEAN MODE)
+ 
MATCH(`text`) AGAINST('code' IN BOOLEAN MODE) AS score
FROM A 
WHERE MATCH(`text`) AGAINST('hello' IN BOOLEAN MODE)
OR  MATCH(`text`) AGAINST('code' IN BOOLEAN MODE)
ORDER BY score DESC

上述查询中的别名score 将为每一行及其匹配的分数提供值,因此您可以按降序排列结果以首先显示分数最高的记录。

注意:您可以在 Myisam 中使用全文搜索,但对于 innodb,您可以使用 将您的 Mysql 升级到支持全文搜索的 5.6 innodb 也是

【讨论】:

  • 我该怎么做才能首先列出匹配关键字最多的行。非常感谢@M Khalid
  • @user4094669 如果使用like,您可以这样做MySQL sort by number of occurrences,但在性能方面这将是具有成本效益的解决方案,如果您可以使用全文搜索,那么它会更容易,并且性能也会更好
  • 我尝试了全文搜索,但遇到了麻烦,所以尝试了这个,你能帮我进行全文搜索。 @M 哈立德
  • 我只是做了上面我在更新部分中写的部分。你能不能给我这方面的建议。 @M 哈立德
  • @user4094669 它与更新部分中的原始帖子不同,您匹配完全相同的hello code,但它不会部分匹配,例如分别匹配与hellocode 的行
【解决方案2】:

您可以使用以下代码:

<?php
   $keyword = 'hello code';
   $exloded = explode(' ', $keyword);

   $sql = "SELECT * FROM A WHERE ";


   foreach($exploded as $value):
      $sql .= "text LIKE '" . $value "%' OR ";
   endforeach;

   // remove last 'OR '
   $sql = substr($sql, -3);

   $result = mysqli_query($con, $sql);


   //................
 ?>

【讨论】:

    猜你喜欢
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    相关资源
    最近更新 更多