在 MySQL 中对单词进行词干提取



MySQL中的词干 例如,用户可以搜索"测试","测试"或"测试"。所有这些词都是相互关联的,因为基本词"测试"在所有这些词中都是通用的。 有没有办法获得这样的结果或功能?

MySQL 全文搜索

从历史上看,MyISAM引擎支持全文搜索。在5.6版本之后,MySQL还支持InnoDB存储引擎中的全文搜索。这是个好消息,因为它使开发人员能够从InnoDB的引用完整性,执行事务的能力和行级锁中受益。

在MySQL中,全文搜索基本上有两种方法:自然语言和布尔模式。(第三个选项通过第二个扩展查询增强了自然语言搜索。

自然模式和布尔模式之间的主要区别在于布尔值允许某些运算符作为搜索的一部分。例如,如果查询中的某个单词比其他单词具有更大的相关性,或者如果结果中应存在特定单词等,则可以使用布尔运算符。值得注意的是,在这两种情况下,结果都可以根据MySQL在搜索期间计算的相关性进行排序。

最适合我们的问题是在布尔模式下使用 InnoDb 全文搜索。为什么?

  • 我们几乎没有时间实现搜索功能。
  • 在这一点上,我们没有大数据需要处理,也没有大量的负载需要像Elasticsearch或Sphinx这样的东西。
  • 我们使用不支持Elasticsearch或Sphinx的共享主机,现阶段硬件非常有限。
  • 虽然我们希望在搜索函数中使用词干,但它并不是一个交易破坏者:我们可以通过一些简单的PHP编码和数据非规范化来实现它(在约束范围内)。
  • 布尔模式下的全文搜索可以搜索带有通配符的单词(针对单词词干),并根据相关性对结果进行排序。

在归一化Vertabelo模型中

让我们看看简单的搜索是如何工作的。我们将首先创建一个示例表:

CREATE TABLE artists (
id int(11) NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL,bio text NOT NULL, CONSTRAINT artists_pk PRIMARY KEY (id)
)ENGINE InnoDB;
CREATE  FULLTEXT INDEX artists_idx_1 ON artists (name);

在自然语言模式下

您可以插入一些示例数据并开始测试。(最好将其添加到示例数据集中。例如,我们将尝试搜索迈克尔杰克逊:

SELECT
*
FROM
artists
WHERE
MATCH (artists.name) AGAINST ('Michael Jackson' IN NATURAL LANGUAGE MODE)

此查询将查找与搜索词匹配的记录,并按相关性对匹配记录进行排序;匹配越好,相关性越高,结果在列表中显示的位置就越高。 在布尔模式下

我们可以在布尔模式下执行相同的搜索。如果我们不对查询应用任何运算符,唯一的区别是结果不按相关性排序:

SELECT
*
FROM
artists
WHERE
MATCH (artists.name) AGAINST ('Michael Jackson' IN BOOLEAN MODE)

布尔模式下的通配符运算符

由于我们要搜索词干词和部分词,因此我们需要通配符运算符 (*)。此运算符可用于布尔模式搜索,这就是我们选择该模式的原因。

因此,让我们释放布尔搜索的力量,并尝试搜索艺术家姓名的一部分。我们将使用通配符运算符来匹配任何名字以"Mich"开头的艺术家:

SELECT
*
FROM
artists
WHERE
MATCH (name) AGAINST ('Mich*' IN BOOLEAN MODE)

最新更新