MATCH AGAINST
描述
该表达式用于在全文索引上进行文本检索,AGAINST 接受一个查找字符串,并且按照字符集的比较方式在索引中进行查找,对于表中的每一行数据,MATCH 的返回值代表了查找字符串和行中数据的相关度,也就是查找字符串中的文本和数据表中的文本相似度。
语法
MATCH (column_set) AGAINST (query_expr [mode_flag])
column_set:
column_name [, column_name ...]
mode_flag:
IN NATURAL LANGUAGE MODE
| IN BOOLEAN MODE
参数解释
| 字段 | 说明 |
|---|---|
| column_set | 指定要进行全文搜索的列。如果要列出多个列,列之间需要使用英文逗号分隔,查询与其中的列顺序无关,必须存在一个被索引列与 column_set 完全匹配的全文索引才可以执行对应的 MATCH AGAINST 表达式。 |
| query_expr | 指定要搜索的关键字或短语,也就是待匹配的参数。seekdb 会按匹配的全文索引使用的分词器对 query_expr 进行分词后,在全文索引上进行检索。 |
| mode_flag | 可选项,表示全文搜索的模式。缺省值为 IN NATURAL LANGUAGE MODE。详细介绍可参见下文 mode_flag。 |
mode_flag
-
IN NATURAL LANGUAGE MODE:默认值,用于指定使用自然语言搜索模式进行搜索。该模式的全文搜索是通过对查询表达式(query_expr)进行分词得到词条(token)集合,与索引中的词条(token)进行匹配来进行检索,只要有一个词条与查询表达式中的词条匹配成功就视为匹配成功。同时会通过基于词频的方法(Okapi BM25)对被匹配成功的行相关性进行 ranking(排序)。默认情况下或者指定
IN NATURAL LANGUAGE MODE标示符,MATCH AGAINST将使用NATURAL LANGUAGE模式来进行全文查找。在NATURAL LANGUAGE模式下,AGAINST接受一个查找字符串,并且按照字符集的比较方式在索引中进行查找,对于表中的每一行数据,MATCH的返回值代表了查找字符串和行中数据的相关度,也就是查找字符串中的文本和数据表中的文本相似度。 -
IN BOOLEAN MODE:用于指定使用布尔模式进行搜索。当前版本支持三种最常用的布尔运算符,以及运算嵌套,具体如下:-
+:表示AND,交集。 -
-:表示非,差集。 -
无操作符号:单独使用时表示
OR,并集,如A B表示A OR B。和符号混用会让存在的句子相关性变高,但会失去OR的语意,如+A B时,表示必须有 A,并计算句子中 A 和 B 的相关性。 -
():表示运算嵌套。外层无符号时,有OR的语意,如+A (嵌套子句),表示必须有 A 或者有嵌套子句。示例如下:
-
输出句子必须包含 computer。
SELECT * FROM my_table WHERE MATCH (doc) AGAINST ("+computer" IN BOOLEAN MODE); -
输出句子必须包含 computer,且一定不包含 weather。
SELECT * FROM my_table WHERE MATCH (doc) AGAINST ("+computer -weather" IN BOOLEAN MODE); -
输出句子必须包含 computer,有 oceanbase 更匹配。
SELECT * FROM my_table WHERE MATCH (doc) AGAINST ("+computer oceanbase" IN BOOLEAN MODE);
-
-
使用说明
MATCH AGAINST 表达式除了表示文本匹配外,在 SQL 的不同子句中出现时还包含一些其他的语义:
-
投影相关性:
- 全文搜索支持基于词频的 ranking,可以通过 MATCH AGAINST 表达式表示相关性的投影。
- 相关性表示匹配的数据行与 MATCH AGAINST 的查询(Query)之间的相关程度。
- 相关性是大于等于 0 的
DOUBLE类型数据,等于 0 表示数据行与查询(Query)无关,数值越大相关性越强。
-
过滤语义:
-
对于在
WHERE子句中出现的MATCH AGAINST表达式,且与其他所有过滤条件通过AND连接时包含过滤语义,表示会过滤掉不匹配的数据行。示例如下:
SELECT id, digest, detail
FROM t1
WHERE MATCH (detail) AGAINST ('oceanbase');等价于
SELECT id, digest, detail
FROM t1
WHERE MATCH (detail) AGAINST ('oceanbase') > 0;
-
-
排序语义:
- 对于
WHERE子句中和其他过滤条件通过AND连接的MATCH AGAINST表达式,包含排序语义。 - 表示会对全文搜索的结果按
MATCH AGAINST的相关序 ranking 降序排序。 - 当存在多个
MATCH AGAINST表达式时,会按第一个MATCH AGAINST的相关性排序。
示例如下:
SELECT id, digest, MATCH (detail) AGAINST ('oceanbase') AS relevance
FROM t1
WHERE MATCH (detail) against ('oceanbase');等价于
SELECT id, digest, MATCH (detail) AGAINST ('oceanbase') AS relevance
FROM t1
WHERE MATCH (detail) AGAINST ('oceanbase')
ORDER BY relevance DESC; - 对于
文本检索的执行方式
-
当 SQL 中的
MATCH AGAINST包含过滤语义时,seekdb 可以通过扫描全文索引计算MATCH AGAINST表达式后回表的方式执行查询。 -
当 SQL 中的
MATCH AGAINST不包含过滤语义时,seekdb 支持通过其他二级索引进行扫描和过滤,并根据主键随机访问全文索引的方式计算MATCH AGAINST表达式来执行查询。 -
当 SQL 的
WHERE子句中包含MATCH AGAINST和通过AND连接的多个过滤条件,且可以命中其他二级索引时,seekdb 会尝试根据代价选择合适的索引进行扫描。 -
当通过扫描全文索引计算
MATCH AGAINST时,如果 Query 中包含LIMIT,seekdb 会尝试将 top-k 计算下压到全文索引扫描中执行来获得更好的性能。 -
在查询包含
OR连接的MATCH AGAINST谓词时,会自动尝试生成 Index Merge 计划,最终是否选择 Index Merge 计划取决于代价竞争的结果。
示例
-
创建示例表
test_tbl1,同时创建全文索引ft_idx1_test_tbl1和ft_idx1_test_tbl1,及索引idx_test_tbl1。CREATE TABLE test_tbl1(id INT, ref_no INT, digest VARCHAR(512), detail VARCHAR(4096),
FULLTEXT INDEX ft_idx1_test_tbl1(detail),
FULLTEXT INDEX ft_idx2_test_tbl1(digest, detail),
INDEX idx_test_tbl1 (id)); -
向表
test_tbl1中插入测试数据。INSERT INTO test_tbl1 VALUES
(1, 1234, 'fulltext', 'Try text retrieval with OceanBase fulltext index'),
(2, 2345, 'log', 'OceanBase can halp with log analysis'),
(3, 3456, 'order', 'Simple text retrieval scan will return result set in order of descending ranking in OceanBase'),
(4, 4567, 'ranking', 'OceanBase will ranking relevance to query for matched result set'),
(5, 5678, 'filter', 'Using text retrieval as a filter condition would be probably more efficient'); -
通过
MATCH AGAINST表达式投影相关性。SELECT id, digest, detail, MATCH (detail) AGAINST ('oceanbase') AS relevance
FROM test_tbl1;返回结果如下:
+------+----------+-----------------------------------------------------------------------------------------------+--------------------+
| id | digest | detail | relevance |
+------+----------+-----------------------------------------------------------------------------------------------+--------------------+
| 1 | fulltext | Try text retrieval with OceanBase fulltext index | 0.2989130434782609 |
| 2 | log | OceanBase can halp with log analysis | 0.3142857142857143 |
| 3 | order | Simple text retrieval scan will return result set in order of descending ranking in OceanBase | 0.240174672489083 |
| 4 | ranking | OceanBase will ranking relevance to query for matched result set | 0.2849740932642488 |
| 5 | filter | Using text retrieval as a filter condition would be probably more efficient | 0 |
+------+----------+-----------------------------------------------------------------------------------------------+--------------------+
5 rows in set (0.003 sec) -
通过
MATCH AGAINST表达式进行过滤。SELECT id, digest, detail
FROM test_tbl1
WHERE MATCH (detail) AGAINST ('oceanbase');返回结果如下:
+------+----------+-----------------------------------------------------------------------------------------------+
| id | digest | detail |
+------+----------+-----------------------------------------------------------------------------------------------+
| 2 | log | OceanBase can halp with log analysis |
| 1 | fulltext | Try text retrieval with OceanBase fulltext index |
| 4 | ranking | OceanBase will ranking relevance to query for matched result set |
| 3 | order | Simple text retrieval scan will return result set in order of descending ranking in OceanBase |
+------+----------+-----------------------------------------------------------------------------------------------+
4 rows in set (0.002 sec) -
通过
MATCH AGAINST表达式进行检索和排序。SELECT id, digest, MATCH (detail) AGAINST ('oceanbase') AS relevance
FROM test_tbl1
WHERE MATCH (detail) AGAINST ('oceanbase');或者
SELECT id, digest, MATCH (detail) AGAINST ('oceanbase') AS relevance
FROM test_tbl1
WHERE MATCH (detail) AGAINST ('oceanbase')
ORDER BY relevance DESC;返回结果如下:
+------+----------+--------------------+
| id | digest | relevance |
+------+----------+--------------------+
| 2 | log | 0.3142857142857143 |
| 1 | fulltext | 0.2989130434782609 |
| 4 | ranking | 0.2849740932642488 |
| 3 | order | 0.240174672489083 |
+------+----------+--------------------+
4 rows in set (0.002 sec)