MySQL 布尔全文搜索

一、MySQL 布尔全文搜索 介绍

布尔搜索模式是 MySQL 中全文搜索的另一种形式。它比自然语言搜索更受单词驱动,这意味着它搜索的是单词而不是概念。它允许我们基于非常复杂的查询进行搜索,这些查询包括布尔运算符,例如小于 (<) 或大于 (>) 运算符、加号 (+) 和减号 (-)、子表达式 ("(" 和 " )")、双引号 ("")、降低值对结果 (~) 和通配符的贡献的运算符。

因此,这种搜索模式适合有经验的用户,因为它提供了一种执行一些非常高级的搜索的方法。通过在 AGAINST 函数中包含IN BOOLEAN MODE 修饰符,我们可以在此模式下执行全文搜索。

让我们用一个基本的例子来理解它。假设我们有一个名为posts的表,其中包含以下数据:

以下示例显示有关如何搜索名称中包含“Java”单词的帖子标题的结果:

mysql> SELECT id, title FROM posts   
WHERE MATCH(title, descriptions)   
AGAINST('Java' IN BOOLEAN MODE);  

执行查询将返回两个包含 Java 单词的帖子名称:

假设我们想要获取帖子名称包含“MySQL”一词但不包含任何其他行包含“Java”一词的帖子。在这种情况下,我们可以使用排除布尔运算符 (-)来获得所需的输出。请参阅以下查询:

mysql> SELECT id, title FROM posts   
WHERE MATCH (title, descriptions)   
AGAINST ('MySQL -Java' IN BOOLEAN MODE);  

执行查询将返回包含MySQL的帖子名称单词,而不是Java单词:

二、相关分数

MATCH() 函数为表中的每一行分配一个相关性值,并将它们作为最高相关性排在首位。此值确定它与搜索词的相关程度。相关性分数总是以非负浮点数的形式出现。

如果我们要检查文本相关性并根据最高相关性对行进行排序,我们可以使用如下查询:

mysql> SELECT title, MATCH (title, descriptions)   
AGAINST ('Java, Workbench' IN BOOLEAN MODE) AS relevance_score   
FROM Posts WHERE MATCH (title, descriptions)   
AGAINST ('Java, Workbench' IN BOOLEAN MODE);  

执行查询,我们会得到想要的结果:

下面是另一个示例,它列出了每一行的相关值,即使该值为零。我们可以在不使用WHERE 子句中的 MATCH() 函数的情况下得到这个结果,这是声明:

mysql> SELECT title, MATCH (title, descriptions)   
AGAINST ('Java, Workbench' IN BOOLEAN MODE) AS relevance_score   
FROM Posts;  

执行查询,我们会得到想要的结果:

三、MySQL 布尔全文搜索 搜索运算符

下表显示了全文布尔搜索模式中使用的运算符及其含义:

运算符 说明
+ 表示搜索字符串的前导或尾随加号必须出现在每个返回的行中。
- 表示搜索字符串的前导或尾随减号不得出现在任何返回的行中。
> 它用于更改单词对分配给行的相关值的贡献。> 运算符增加相关值。
< 它用于更改单词对分配给行的相关值的贡献。> 运算符降低相关性值。
* 它表示单词末尾的通配符。
~ 它充当否定词的排名值的否定运算符。它在标记噪声词时很有用。
“” 它定义了一个用双引号 (") 字符括起来的短语。它匹配整个短语以包含或排除,而不是单个单词。
() 括号运算符用于将单词分组为子表达式。它也可以嵌套,并允许它们作为一个组被包含、排除、排名等。
@distance 它仅用于测试两个或多个单词是否在指定距离内开始的 InnoDB 表。
No operator 如果我们既没有使用加号或减号运算符,默认情况下,该词是可选的,但行的评级较高。

让我们看一下说明在搜索查询中使用布尔全文运算符的各种示例:

1. 如果我们要搜索至少包含以下单词之一的行:Java 或 tutorial,我们可以使用以下语句:

mysql> SELECT id, title FROM posts   
WHERE MATCH(title, descriptions)   
AGAINST('Java tutorial' IN BOOLEAN MODE);  

 2. 如果我们要搜索包含两个单词的行:Java 和 tutorial,我们可以使用以下语句:

mysql> SELECT id, title FROM posts   
WHERE MATCH(title, descriptions)   
AGAINST('+Java +tutorial' IN BOOLEAN MODE);  

3. 如果我们要搜索包含单词 Java 的行,但对包含 MySQL 的行放置更高的排名:

mysql> SELECT id, title FROM posts   
WHERE MATCH(title, descriptions)   
AGAINST('+Java tutorial' IN BOOLEAN MODE);  

4. 如果我们要搜索包含单词 Java 的行,但对包含 MySQL 的行放置较低的排名:

mysql> SELECT id, title FROM posts   
WHERE MATCH(title, descriptions)   
AGAINST('+Java ~tutorial' IN BOOLEAN MODE);  

5. 如果我们想查找包含以“my”开头的单词的行,例如“MySQL”,我们使用以下查询:

mysql> SELECT id, title FROM posts   
WHERE MATCH(title, descriptions)   
AGAINST('My*' IN BOOLEAN MODE);  

四、MySQL 布尔全文搜索 特征

  • MySQL 布尔全文搜索不会自动按照相关性递减的顺序对行进行排序。
  • 如果我们想在 InnoDB 表中执行布尔查询,它需要对 MATCH 表达式的所有列进行全文索引。然而,在 MyISAM 表中它不是必需的,但在这里搜索会变慢。
  • InnoDB 表上的全文搜索不支持单个搜索词上的多个布尔运算符,例如 ' ++database'。如果我们这样做,MySQL 将返回语法错误。但是,它可以在忽略其他运算符并使用与搜索词相邻的那个运算符的 MyISAM 表中进行处理;例如,“ +-database”将变为“ -database”。
  • InnoDB 全文搜索仅支持前导加号 (+) 或减号 (-),不支持尾随加号或减号。如果我们这样做,MySQL 将报告语法错误。例如,我们可以在 InnoDB 中搜索“+database”,但不能搜索“database-”。此外,我们不能将前导加号或减号与通配符一起使用:+*、+- 等。
  • MySQL 将忽略搜索结果中的50% 阈值(该词出现在超过 50% 的行中)。
  • MySQL InnoDB 全文搜索确实允许在布尔全文搜索中使用 @ 符号。

热门文章

优秀文章