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

时间:2014-09-30 11:08:32

标签: php mysql

我有一个搜索公司的系统。我希望当用户搜索“Demo”时,将返回所有具有“Demo”的记录,例如“The Demo”,“Demo Inc.”等。我不希望那些记录像“民主”,“拆迁“等我认为你明白我的意思。

现在,我的工作查询看起来像这样:

select * from table where company LIKE "Demo%"

但这确实没有达到我的要求。我也试过这个:

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

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

9 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

根据我的评论在黑暗中拍摄。如果你总是得到一个完全匹配的标准。是不是最好执行标准选择查询?

SELECT * FROM table WHERE company='The Demo'

或实际:

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

使用用户输入时,显然使用最佳做法&amp;查询。

绘制的结果将是找到的行演示演示将被返回或没有。


如果你没有完全匹配。您可以再次使用带有附加值的$ _GET,即$ _GET [&#39; Exact&#39;]&amp;有两个不同的功能:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我不明白为什么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 
 }
}

答案 4 :(得分:0)

最佳解决方案是创建全文索引:

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

然后你可以搜索:

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

详细了解mysql full text search

根据您的MySQL版本,全文索引可用于版本5.5或更低版本的MyISAM,自5.6以来可用于InnoDB。

答案 5 :(得分:0)

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

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

另一种解决方案

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

SQL Fiddle Demo

答案 6 :(得分:0)

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

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

答案 7 :(得分:-1)

试试这可能对你有帮助..

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

答案 8 :(得分:-2)

尝试测试两侧的空间:

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

但是,正如您所说,您需要使用索引,并且带有前导通配符%的任何内容都不会使用索引。

因此,我认为您需要在搜索列上实现某种预处理,类似于:

预处理您的记录名称:

  • 对数据库中的所有记录名称使用stemming算法
  • 将词干词存储在一个表格中( 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)

Here's a basic tutorial to get you started with stemming and word counts