忽略MySQL全文检索中的停用词在查询中。

14
我正在为网站构建搜索功能,使用了全文搜索。搜索本身效果很好,这不是我的问题。我将用户提供的关键词(MATCH...AGAINST...)用AND连接起来,以便进一步缩小结果范围。现在,我知道某些停止词没有索引,对我来说没关系,我真的不想将它们用作选择标准。但是,如果用户提供的关键词集中有停用词,则即使该单词实际上存在于某个文本块中,它也会使所有结果都无法显示(按预期)。
我的问题是:是否有任何方法可以在查询时检查某个词是否为停用词?我倾向于从搜索条件中排除相关词语(我不介意用户通过单词“neither”缩小结果,但我只是不希望MySQL返回一个空结果集,因为用户提供了它,尽管实际结果中不存在)。或者,我只能清空停用词列表吗?非常感谢您的任何帮助。
编辑---- 很抱歉,但是这个问题真的没有代码片段可提供。代码实际上完全按照预期工作。这更多是一个逻辑问题。但是,作为解释的例子:
假设有三条记录,其中包括以下单词(但不限于)
1:苹果,橘子,芒果,香蕉 2:葡萄,橘子,菠萝,芒果 3:土豆,芒果,甜瓜,凯拉·奈特利
如果用户输入的搜索词是“芒果”,则所有结果都将正确返回。如果搜索词是“橘子”和“芒果”,则会返回1和2号结果(正确)。现在,假设“香蕉”是停用词(实际上并不是...但是我们假设它是),如果搜索的内容是橘子、芒果和香蕉,则不会返回任何结果(因为香蕉不在全文索引中)。
我想知道是否有其他人遇到过这个问题,并且有没有解决方法。类似于:
if 'banana' NOT STOP WORD match 'banana' against `words`. (OBVIOUSLY not real code).

那么...我是不是只能放弃停用词列表了...


你尝试了什么?你能给我们提供一些例子吗? - jcho360
似乎没有一个答案真正符合您的要求。您可以编写应用程序代码来手动过滤查询中的任何停用词(以及太短的单词)。这可能是我们将要做的事情。 - Nathan Stretch
2017年,这里也有同样的问题。似乎MySQL全文搜索设计非常糟糕,缺乏基本功能。 - jgr
6个回答

12

您可以通过比较所有停用词来验证关键字。以下是停用词列表。 我已经找到了一种从全文检索中禁用停用词的解决方案。 您只需要找到.cnf文件并添加以下内容:

ft_stopword_file = ""

重新启动MySQL引擎并重建索引;

希望这能起作用


我在考虑这可能是我需要走的路线。我只是真的希望有人有更聪明的解决方案。感谢您的意见。 - dgeare

3
如何在MySQL中禁用全文停用词:
在my.ini文本文件(MySQL)中:
[mysqld] ft_stopword_file=""
ft_stopword_file = ""   or link an empty file "empty_stopwords.txt"
ft_min_word_len = 2 

//设置最小长度,但要注意较短的单词(3、2)会大大增加查询时间,特别是如果全文索引列字段很大。

保存文件,重新启动服务器。

下一步应该使用以下查询修复索引:

REPAIR TABLE tbl_name QUICK.

然而,如果您的表使用InnoDB存储引擎,则此方法将无法奏效。您需要将其更改为MyISAM:

ALTER TABLE t1 ENGINE = MyISAM;

所以,再次强调:
1. Edit my.ini file and save
2. Restart your server (this cannot be done dynamically)
3. Change the table engine (if needed)  ALTER TABLE tbl_name ENGINE = MyISAM;
4. Perform repair                       REPAIR TABLE tbl_name QUICK.

请注意,InnoDB和MyISAM之间存在速度差异。其中一个读取更快,另一个写入更快(请在互联网上了解更多)。

2
需要注意的是,MySQL 5.6 中的 InnoDB 具有全文索引功能。 - Félix Adriyel Gagnon-Grenier

2

对于INNODB情况,当您创建索引时可以禁用stop_words。

SET @@SESSION.innodb_ft_enable_stopword = 'OFF';

create table foo
....
fulltext (search_col)

这将导致全文索引被创建时停用停用词。您可以通过使用以下查询来验证。

SET GLOBAL innodb_ft_aux_table = 'schema/foo';
select * from information_schema.innodb_ft_config;

你的结果将会是这样的: 在此输入图片描述 请注意,use_stopword 被设置为 0。
mysql 文档页面 上搜索 use_stopwords,并在 这里 检查 innodb_ft_enable_stopword。

1

使用以下步骤在MySQL中禁用全文搜索的停用词:

1:打开MySQL中的my.ini文件

2:在my.ini文件中的[mysqld]行之后插入以下两行代码(搜索文件中的[mysqld])

ft_min_word_len=1
ft_stopword_file=""

3:重新启动您的服务器。

4:使用以下命令修复您的表格。

 > repair table tablename;

5:现在您的搜索功能已经可用....


0

设置 ft_stopword_file = ""
对我没有用,我正在使用INNODB表和MySQL 5.6(在优化相关表后,停用词仍未在全文索引中索引)

这个解决方案有效(即使您不是超级用户):

CREATE TABLE mydb.stopwordslist(value VARCHAR(20)) ENGINE = INNODB;
INSERT INTO mydb.stopwordslist(value) VALUES ('skipthisword');

对于所有用户,但您仍然需要超级用户权限:

SET GLOBAL innodb_ft_server_stopword_table = 'mydb/stopwordslist';

仅适用于用户(假设是重新创建索引和更新列的用户)

SET SESSION innodb_ft_user_stopword_table = 'mydb/stopwordslist';

由于它是一个会话变量,所以当您的会话关闭时,它将不会持续存在,请确保在每个会话或在优化或插入具有全文索引的表之前设置它,或者在更新由全文索引索引的列时设置。


-4

尝试使用MATCH...AGAINST...IN BOOLEAN MODE 像这样: WHERE MATCH(author,title) AGAINST('"起源"' IN BOOLEAN MODE);


停用词不在全文索引中,因此即使使用布尔模式,它也不会返回任何结果。 - Laurent PELE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接