如何在 MySQL 中使用全文搜索
全文搜索是一种数据库技术,即使记录与我们的搜索条件不完全匹配,它也会检索记录。 这使得感觉更熟悉的丰富的自然语言搜索成为可能。
使用全文搜索来搜索“database engine”将返回包含短语“database”、“engine”或“database engine”的结果。 这解决了搜索条件中可能存在的歧义,因此像“I have a database and an engine”这样的行仍然会出现。
可以使用 LIKE
运算符在 MySQL 中进行简单搜索。 这是低效的并且功能有限。 MySQL 通常需要执行全表扫描来识别与我们的查询匹配的记录。
全文查询使用专门创建的索引来提高性能。 这也使 MySQL 能够跟踪数据集中的单词,从而促进自然语言搜索。
设置全文搜索
我们只能对具有全文索引的列使用全文搜索。 在为数据库模式设置种子时,使用 CREATE TABLE
语句中的 FULLTEXT
子句进行设置。 我们还可以将它与 ALTER TABLE
一起使用,以将搜索索引添加到现有列。
CREATE TABLE articles(content TEXT, FULLTEXT (content));
ALTER TABLE articles ADD FULLTEXT (content);
有了索引,我们就可以开始查询数据库了。
使用全文搜索
全文搜索以 WHERE
子句开始。 我们使用 MATCH AGAINST
而不是 LIKE
。 我们需要指明要匹配的索引列,以及要搜索的查询。
SELECT * FROM articles WHERE MATCH (content) AGAINST ('database engine' IN NATURAL LANGUAGE MODE);
这将使用查询数据库引擎执行文章的全文搜索。 通过指定 IN NATURAL LANGUAGE MODE
,MySQL 被指示按字面解释查询,而不以任何方式处理它。 如果未指定,则这是默认搜索模式。
按结果相关性排序
全文搜索的优点之一是它允许我们按相关性对返回的记录进行排序。 这对于常规的 LIKE
查询是不可能的。 我们可以使用 MATCH ... AGAINST
子句作为 SQL SELECT
的一部分。 返回的虚拟列将包含一个从 0 到 1 的相关性分数,表示记录与搜索查询的匹配程度。
SELECT content, MATCH (content) AGAINST ('database engine') AS relevance FROM articles ORDER BY relevance DESC
此查询将首先返回最相关的结果。 这有助于我们的应用程序满足用户对自然语言搜索系统应如何执行的期望。
MySQL 通过评估几个不同的因素来计算搜索相关分数。 其中包括与查询匹配的记录数,以及查询在每条记录中出现的次数。 具有多个与查询完全匹配的结果将比仅包含部分查询的结果排名更高。
在 SELECT
语句中使用 MATCH ... AGAINST
时,不需要在 WHERE
子句中重复它。 我们可以手动过滤结果以仅包含具有非零相关性分数的记录。
SELECT content, MATCH (content) AGAINST ('database engine') AS relevance FROM articles WHERE relevance > 0 ORDER BY relevance DESC
查询扩展模式
自然语言不是唯一受支持的全文搜索模式。 查询扩展模式是一种替代方法,有助于扩大搜索结果的范围。 它会自动根据最相关的术语对搜索查询进行加权。
扩展搜索首先查找包含查询匹配项的记录。 然后检查这些记录以识别最相关的词。 然后数据库运行另一次搜索,这次是基于相关词而不是原始查询。 这通常会导致返回更多记录,同时保持可接受的相关度。
以下是启用查询扩展模式的方法:
SELECT * FROM articles WHERE MATCH (content) AGAINST ('database engine' WITH QUERY EXPANSION)
布尔模式
最后的全文搜索模式是布尔模式。 这使我们可以在查询中包含布尔修饰符。 当我们需要对匹配逻辑进行高级控制时,可以使用此模式。
我们可以通过在单词前加上 +
来要求单词出现在每个结果中。 使用 -
排除包含该词的结果。 其他运算符可用于匹配单词的部分,创建子表达式并使单词降低相关性分数。 后者在屏蔽“噪音”项时很有用。 如果我们不指定运算符,则暗示该词将在查询中使用 OR
进行引用。
SELECT * FROM articles WHERE MATCH (content) AGAINST ('+data* engine -sqlite' IN BOOLEAN MODE)
此查询将显示至少有一个以未提及 sqlite
的数据开头的单词的文章。 每个结果可能包含也可能不包含单词引擎。
布尔模式允许我们使用自己的逻辑构建强大的搜索。 一个警告是它不支持搜索相关性评分。 这是让用户能够进行布尔搜索的权衡。 结果排名可能与人类预期不符。
配置全文搜索
MySQL 带有几个全文配置选项,可让我们微调搜索的执行方式。 这里有一些最重要的。
-
innodb_ft_min_token_size – 设置索引术语的最小字长。 字符少于此值的单词不会添加到索引中,因此我们将无法搜索它们。 默认值为 3,排除了 a、an 和 I 等极其常见的词。此设置适用于 InnoDB 表; 对 MyISAM 使用
ft_min_word_len
。 -
innodb_ft_max_token_size——类似于
innodb_ft_min_token_size
,这设置了索引词的最大长度。 较长的词将无法搜索。 对 MyISAM 表使用ft_max_word_len
。 - innodb_ft_enable_stopword – 默认情况下,此设置允许我们控制 MySQL 是否应过滤掉“停用词”。 停用词是非常常用的词,可能会过度影响搜索结果。 默认停用词列表包含 36 个常用短语。
-
innodb_ft_user_stopword_table – 我们可以将此值设置为数据库表的名称,MySQL 应该从中获取停用词列表。 该表必须有一个名为 value 的
VARCHAR
列。 添加我们停用词以作为该表中的记录排除。
这些设置通常在我们的 MySQL 服务器配置文件中设置。 位置因平台而异; 它通常可以在 /etc/mysql/my.cnf 中找到。 更改设置后需要重启 MySQL 服务。
服务器备份后,重建表的全文索引。 我们必须这样做,以便使用当前配置为我们的数据重新编制索引。 否则,将继续使用先前索引的数据。
要重新索引 InnoDB 表,请运行 OPTIMIZE TABLE my_table
。 对于 MyISAM 表,使用 REPAIR TABLE my_table QUICK
。 然后将重建搜索索引,以便我们的配置更改生效。
总结
通过向可搜索字段添加全文索引来启用 MySQL 全文搜索。 然后,我们使用 MATCH ... AGAINST
和三种搜索模式之一来获得结果。 自然语言查询会返回一个搜索相关性分数,我们可以使用该分数对结果进行排名。
全文搜索提供比 LIKE
语句更强大的搜索行为。 它的性能也更高,尤其是在大型数据集上,因为所有文本都已预先编制索引。
相关文章
使用 Mysqldump 备份 MySQL 中的数据
发布时间:2023/05/09 浏览次数:192 分类:MySQL
-
本篇文章将介绍如何使用 mysqldump 只备份数据。 在这里,我们将探讨 --no-create-info 、--compact 、--skip-triggers 和 --no-create-db 选项。
更新 MySQL 表中的主键
发布时间:2023/05/09 浏览次数:61 分类:MySQL
-
本篇文章介绍如何更新 MySQL 表中的主键。 我们将使用 ALTER 命令对主键进行任何更改。更新 MySQL 表中的主键 我们可以在多种情况下更新 MySQL 表中的主键。
在 MySQL 中获取命令历史记录
发布时间:2023/05/09 浏览次数:150 分类:MySQL
-
本文重点介绍了在 Windows 和 Linux 中获取我们已执行的 MySQL 命令历史记录的各种方法。MySQL命令历史
Oracle 的 decode 函数在 MySQL 中的等价物
发布时间:2023/05/09 浏览次数:115 分类:MySQL
-
本篇文章介绍了三种替代实现,我们可以将它们用作 MySQL 中 Oracle 的 decode() 函数的等价物。 为此,我们将使用 IF()、CASE 以及 FIELD() 和 ELT() 的组合。
使用 Ubuntu 连接远程 MySQL 服务器的不同方法
发布时间:2023/05/09 浏览次数:97 分类:MySQL
-
在本文中我们将学习如何使用 Ubuntu 连接远程 MySQL 服务器来操作数据以及启动和停止 MySQL 服务器。
在 Linux 中安装 MySQL 客户端
发布时间:2023/05/09 浏览次数:72 分类:MySQL
-
在 Linux 中安装 MySQL 客户端的命令。Linux 和 Unix 等环境作为命令行界面工作,仅在命令的帮助下运行。
在 MySQL 中转换为十进制
发布时间:2023/05/09 浏览次数:150 分类:MySQL
-
有时,我们可能需要将一种数据类型转换为另一种数据类型。 下面是我们如何使用带有 DECIMAL(M,D) 的 CAST() 和 CONVERT() 函数在 MySQL 中转换为十进制。
在 MySQL 中获取当前日期和时间
发布时间:2023/05/09 浏览次数:145 分类:MySQL
-
本篇文章我们将学习 NOW()、CURRENT_TIMESTAMP()(也写为 CURRENT_TIMESTAMP)和 SYSDATE() 来获取 MySQL 中的当前日期和时间。 我们还将看到这三个功能之间的比较。在 MySQL 中获取当前日期和时间
更改 MySQL 服务器中的 max_allowed_packet Size
发布时间:2023/05/09 浏览次数:142 分类:MySQL
-
本篇文章介绍如何更改 MySQL 服务器中的 max_allowed_packet 大小。 为了了解这一点,我们将使用两个操作系统,Windows 10 和 Linux (Ubuntu)。