全文索引不能搜索带','的内容。 (mysql 5.7.20, MyISAM)

问题描述 投票:0回答:2

我正在尝试使用全文索引来搜索其中包含“,”的内容。

但是我不能,详情如下。(mysql 5.7.20, MyISAM)

如果我在搜索词中加上“,”,我找不到任何结果。

mysql> select * from tmp;                                                                                             
+-----------------+                                                                                                   
| book_name       |                                                                                                   
+-----------------+                                                                                                   
| hi,there        |                                                                                                   
+-----------------+                                                                                                   
1 rows in set (0.00 sec)                                                                                              
                                                                                                                      
mysql> select book_name from tmp where match(book_name) against('"hi,there"' in boolean mode);                        
Empty set (0.00 sec)                                                                                                  

可以看到空集返回了。为什么? 我的设置如下:

                                                                                                                      
mysql> show create table tmp;                                                                                         
show create table tmp;                                                                                                
+-------+--------------+ 
| Table | Create Table |                                                        
+-------+--------------+                                                        
| tmp   | CREATE TABLE `tmp` (                                                                                        
  `book_name` char(32) NOT NULL,                                                                                      
  FULLTEXT KEY `book_name` (`book_name`) /*!50100 WITH PARSER `ngram` */                                              
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 |                                                                             
+-------+--------------+                                                        
1 row in set (0.00 sec)                                                                                               
                                                                                                                      
mysql> show variables like '%ngram%';                                                                                 
show variables like '%ngram%';                                                                                        
+------------------+-------+                                                                                          
| Variable_name    | Value |                                                                                          
+------------------+-------+                                                                                          
| ngram_token_size | 2     |                                                                                          
+------------------+-------+                                                                                          
1 row in set (0.01 sec)                                                                                               
                                                                                                                      
mysql> show variables like '%stopword%';                                                                              
show variables like '%stopword%';                                                                                     
+---------------------------------+-------+                                                                           
| Variable_name                   | Value |                                                                           
+---------------------------------+-------+                                                                           
| ft_stopword_file                |       |                                                                           
| innodb_ft_enable_stopword       | ON    |                                                                           
| innodb_ft_server_stopword_table |       |                                                                           
| innodb_ft_user_stopword_table   |       |                                                                           
+---------------------------------+-------+                                                                           
4 rows in set (0.00 sec)                                                                                              
                                                                                                                      

为什么?

mysql full-text-search
2个回答
1
投票

默认全文索引考虑词,逗号不是词的一部分。来自自然语言全文搜索文档

相关性是根据行(文档)中的单词数、行中唯一单词的数量、集合中的单词总数以及包含特定单词的行数来计算的。

[...]

内置的 FULLTEXT 解析器通过查找特定的分隔符来确定单词的开始和结束位置;例如,(空格)、、(逗号)和 。 (时期)。如果单词没有用分隔符分隔(例如中文),内置的 FULLTEXT 解析器无法确定单词的开始或结束位置。为了能够将此类语言中的单词或其他索引术语添加到使用内置 FULLTEXT 解析器的 FULLTEXT 索引,您必须对它们进行预处理,以便它们由任意定界符分隔。或者,您可以使用 ngram 解析器插件(用于中文、日语或韩语)或 MeCab 解析器插件(用于日语)创建 FULLTEXT 索引。

来自布尔全文搜索文档

用双引号 (") 字符括起来的短语只匹配字面上包含该短语的行,因为它是键入的。全文引擎将短语拆分为单词,并在全文索引中搜索单词。非单词字符不需要完全匹配:短语搜索只需要匹配包含与短语完全相同的单词并且顺序相同。例如,“test phrase”匹配“test, phrase”。

如果您的文本和查询是,例如,“unladen,swallow”,到目前为止一切顺利:您的查询将搜索彼此相邻的词“unladen”和“swallow”,忽略逗号。你没有得到任何结果的原因是因为“hi”低于字长阈值,而“there”在 MyISAM 表中有一个stopword,使你的查询实际上是空的。来自文档:

任何太短的词都会被忽略。全文搜索找到的单词的默认最小长度对于 InnoDB 搜索索引是三个字符,对于 MyISAM 是四个字符。您可以通过在创建索引之前设置配置选项来控制截止:InnoDB 搜索索引的

innodb_ft_min_token_size
配置选项,或 MyISAM 的
ft_min_word_len

换句话说,您真正遇到问题的不是逗号,而是您要搜索的词。如果您的数据和查询是“hi there”,您会得到相同的结果(或者更确切地说,同样缺少结果)。

如果您将索引更改为 ngram 索引,您的查询将起作用,因为它在字符级别而不是单词级别起作用,并且不会区别对待逗号。它仍然使用相同的停用词列表,但它只排除包含停用词的标记;由于您的最大标记大小定义为 2,因此您不能将

there
,甚至
the
作为停用词进行处理。


0
投票

这相关吗?

---- 2018-07-27 8.0.12 全面上市 & 2018-07-27 5.7.23 全面上市 -- -- InnoDB -----

ngram 全文搜索解析器允许将逗号和句点字符标记为单词,这导致布尔和自然语言模式搜索结果之间不一致。逗号和句点字符不再标记化。 (错误号 27847697)

© www.soinside.com 2019 - 2024. All rights reserved.