MySQL全文搜索之谜

Rus*_* C. 4 mysql full-text-search

我们在我们的网站上进行了简单的搜索,使用MySQL全文搜索,由于某种原因,它似乎没有返回正确的结果.我不知道Amazon RDS(我们的数据库服务器所在的位置)或我们请求的查询是否存在某种问题.

这是数据库表的结构:

CREATE TABLE `items` (
  `object_id` int(9) unsigned NOT NULL DEFAULT '0',
  `slug` varchar(100) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`object_id`),
  FULLTEXT KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

这是一个简单的全文搜索查询在这个表和返回的结果:

select object_id ,slug,name from items where MATCH (name) AGAINST ('+ski*' IN BOOLEAN MODE) order by name;

+-----------+-----------------------------------+------------------+
| object_id | slug                              | name             |
+-----------+-----------------------------------+------------------+
|  10146041 | us/new-hampshire/dartmouth-skiway | Dartmouth Skiway |
+-----------+-----------------------------------+------------------+
Run Code Online (Sandbox Code Playgroud)

如果我改为使用LIKE,我会得到一组不同的结果:

select object_id,slug,name from items where name LIKE "%ski%" order by name;

+-----------+------------------------------------------+----------------------------------+
| object_id | slug                                     | name                             |
+-----------+------------------------------------------+----------------------------------+
|  10146546 | us/new-york/brantling-ski                | Brantling Ski                    |
|  10146548 | us/new-york/buffalo-ski-club             | Buffalo Ski Club                 |
|  10146041 | us/new-hampshire/dartmouth-skiway        | Dartmouth Skiway                 |
|  10146352 | us/montana/discover-ski                  | Discover Ski                     |
|  10144882 | us/california/donner-ski-ranch           | Donner Ski Ranch                 |
|  10146970 | us/new-york/hickory-ski-center           | Hickory Ski Center               |
|  10146973 | us/new-york/holimont-ski-area            | Holimont Ski Area                |
|  10146283 | us/minnesota/hyland-ski                  | Hyland Ski                       |
|  10145911 | us/nevada/las-vegas-ski-snowboard-resort | Las Vegas Ski & Snowboard Resort |
|  10146977 | us/new-york/maple-ski-ridge              | Maple Ski Ridge                  |
|  10146774 | us/oregon/mount-hood-ski-bowl            | Mt. Hood Ski Bowl                |
|  10145949 | us/new-mexico/sipapu-ski                 | Sipapu Ski                       |
|  10145952 | us/new-mexico/ski-apache                 | Ski Apache                       |
|  10146584 | us/north-carolina/ski-beech              | Ski Beech                        |
|  10147973 | canada/quebec/ski-bromont                | Ski Bromont                      |
|  10146106 | us/michigan/ski-brule                    | Ski Brule                        |
|  10145597 | us/massachusetts/ski-butternut           | Ski Butternut                    |
|  10145117 | us/colorado/ski-cooper                   | Ski Cooper                       |
|  10146917 | us/pennsylvania/ski-denton               | Ski Denton                       |
|  10145954 | us/new-mexico/ski-santa-fe               | Ski Santa Fe                     |
|  10146918 | us/pennsylvania/ski-sawmill              | Ski Sawmill                      |
|  10145299 | us/illinois/ski-snowstar                 | Ski Snowstar                     |
|  10145138 | us/connecticut/ski-sundown               | Ski Sundown                      |
|  10145598 | us/massachusetts/ski-ward                | Ski Ward                         |
+-----------+------------------------------------------+----------------------------------+
Run Code Online (Sandbox Code Playgroud)

我完全不知道为什么使用全文搜索的查询不起作用.我希望那里的一些MySQL专家可以在我们的查询中指出错误.

在此先感谢您的帮助!

Mic*_*son 5

来自MySQL文档

  • + 前导加号表示该单词必须出现在返回的每一行中.

  • *星号用作截断(或通配符)运算符.与其他运算符不同,它应附加到受影响的单词上.如果单词以*运算符前面的单词开头,则单词匹配.

    如果使用截断运算符指定了单词,则不会从布尔查询中删除它,即使它太短(根据ft_min_word_len设置确定)或停用词.之所以会出现这种情况,是因为该单词不会被视为太短或停用词,而是作为前缀必须以单词形式出现在文档中,该单词以前缀开头.

在上下文中:

比赛(...)反对(...)

MATCH (name) AGAINST ('+ski*' IN BOOLEAN MODE)意味着你正在寻找其中的一个字排name必须包含 ski,并且必须开始用这个词ski.

从您发布的集合中,Dartmouth Skiway唯一name符合这些要求的集合:它包含单词ski,并以单词为前缀ski.

其他name列虽然符合第一条规则:必须包含ski,但它们没有前缀 ski,如规则中所规定的那样.通过您的布尔搜索返回的行是唯一一家拥有name包含一个词都列包含 ski,是一个字为前缀ski.

正如ajreal建议的那样,尝试减少ft_min_len_word_settingin my.cnf.由于默认设置,您的搜索可能无法提供您期望的结果.尝试将其减少到3.

WHERE列LIKE%text%

WHERE name LIKE "%ski%"无论字出现在何处,都会搜索name包含列的行ski.