在 Mysql 中按确切单词搜索字符串


Search string by exact word in Mysql

我有一个搜索公司的系统。我希望当用户搜索"演示"时,将返回所有具有"演示"的记录,例如"演示","演示公司"等。我不想要那些像"民主"、"拆除"等记录。我想你明白我的意思。

现在,我的工作查询如下所示:

select * from table where company LIKE "Demo%"

但这真的不符合我的要求。我也试过这个:

select * from table where company RLIKE "[[:<:]]demo[[:>:]]"

唯一的问题是它消除了我公司字段索引的可能性。所以它的搜索速度真的很慢。我现在有超过一百万条记录。知道怎么做吗?如果它不能在mysql中完成,知道在PHP中是否可以吗?谢谢!

创建一个全文索引,然后您可以更轻松地进行搜索。

ALTER TABLE table ADD FULLTEXT INDEX fulltext_index;

SELECT * FROM table WHERE MATCH (company) AGAINST ('+Demo' IN BOOLEAN MODE); 

dev.mysql.com/doc/refman/5.6/en/fulltext-search.html

您可以使用REGEXP以及[[:<:]][[:>:]]单词边界标记:

SELECT
    *
FROM
    `table`
WHERE
    company REGEXP '[[:<:]]Demo[[:>:]]';

另一种解决方案

SELECT
    *
FROM
    `table`
WHERE
    company REGEXP '(^|[[:space:]])Demo([[:space:]]|$)';

SQL 小提琴演示

根据我的评论,在黑暗中射击。如果您总是会得到一个完全匹配的标准。执行标准选择查询不是最好的吗?

SELECT * FROM table WHERE company='The Demo'

或为实践:

   $Search = $_GET['company'];
   SELECT * FROM table WHERE company='$Search'

显然,在使用用户输入和查询时,请使用最佳实践。

抽取的结果将是找到具有演示的行,演示将被返回或什么都没有。


如果您并不总是完全匹配。您可以再次使用带有附加值的 $_GET,即 $_GET['Exact'] 并具有两个不同的函数:

function ExactMatch ($DB,$Company){
  /* 
    Query to get exact match as exampled 
  */
}
function NotExact($DB,$Company){
  /*
   Query using LIKE syntax 
  */
}

并验证:

if (isset($_GET['Exact'])){
  if ($_GET['Exact'] === 1){
    ExactMatch($DB,$_GET['Company']);
  }else{
    NotExact($DB,$_GET['Company'])
  }
}

另外,DBA.stackexchange上的可能读取:

https://dba.stackexchange.com/questions/39693/how-to-speed-up-queries-on-a-large-220-million-rows-table-9-gig-data

我不明白为什么 1M 是一个问题 我刚刚在我的笔记本电脑 MySQL MyISAM 上测试了它,它也有一家公司,但它是 250K 行,花了 3.3 毫秒,并且该字段没有索引。 你能试试呜�

$search='Demo';
$regex="/'b$search'b/i";
$sql = "select * from table where company like '%$search%';
//... get the results
foreach($results as $companyName){
 if(preg_match($regex,$companyName,$match)){
    //here you got a match 
 }
}
SELECT *
FROM table_name
WHERE company LIKE "% Demo %"
    OR company LIKE "Demo %"
    OR company="Demo";

最好的解决方案是创建一个全文索引:

create fulltext index `i_company` on `table`(`company`);

然后,您可以搜索为:

select * from `table` where match(company) against ('Demo');

阅读有关 mysql 全文搜索的更多信息。

根据您的MySQL版本,全文索引可用于5.5或更低版本的MyISAM,并且从5.6开始可用于InnoDB。

若要从字符串中搜索确切的单词,请使用以下查询

select
*
from tablename 
where column_name regexp '(^|[[:space:]])wordyouwanttosearch([[:space:]]|$)';

试试这个可能会有所帮助。

 SELECT * FROM table_name WHERE company LIKE "%Demo%";

尝试测试两侧的空间:

select * from table where company LIKE "Demo %" OR company LIKE "% Demo"

但是,正如您所说,您需要使用索引,任何具有前导通配符%都不会使用这些索引。

因此,我认为您需要对搜索列进行某种预处理,大致如下:

预处理您的记录名称:

  • 对数据库中的所有记录名称使用词干分析算法
  • 将词干单词存储在一个表中 (stemmed_words(
  • 根据记录 ID 记录词干单词的出现次数 (record_index(

然后,当用户搜索时:

  • 对搜索词使用词干算法
  • 查询表以查找包含最常用词干词的结果

示例stemmed_words表列:

id, stemmed_word  // Eg. 1 (auto generated), "Demo"

示例record_index表列:

record_id, stemmed_word_id, occurrence_count // Eg. 1 (auto generated), 1 (ID of "Demo" in stemmed_words table), 2 (2 occurrences)

这是一个基本教程,可帮助您开始使用词干提取和字数统计