自3.3.13-1.0.0版本起,StarRocks支持全文倒排索引功能。该功能对文本中的每个单词进行分词处理,并为每个词建立相应的索引项,以记录该单词与其所在数据文件行号之间的映射关系。在进行全文检索时,StarRocks将根据查询的关键词对倒排索引进行访问,从而快速定位与关键词匹配的数据行。
使用限制
仅支持3.3.13-1.0.0及以上版本的实例。
仅支持明细表和主键表。
仅支持为CHAR、VARCHAR和STRING类型创建倒排索引。
在存算一体实例中使用时,需要设置表属性
replicated_storage=false
。
创建全文倒排索引
在StarRocks控制台的参数配置页签,设置FE配置项
enable_experimental_gin
为true
,以启用全文倒排索引。在SQL Editor页签中,根据建表情况选择创建全文倒排索引。
方式一:建表时创建
以下以存算一体实例为例,基于列
v
构建全文倒排索引并且使用英文分词。CREATE TABLE `t` ( `k` BIGINT NOT NULL COMMENT "", `v` STRING COMMENT "", INDEX idx (v) USING GIN("parser" = "english") ) ENGINE=OLAP DUPLICATE KEY(`k`) DISTRIBUTED BY HASH(`k`) BUCKETS 1 PROPERTIES ( "replicated_storage" = "false" );
方式二:建表后创建
通过
ALTER TABLE ADD INDEX
添加全文倒排索引ALTER TABLE t ADD INDEX idx (v) USING GIN('parser' = 'english');
通过
CREATE INDEX
添加全文倒排索引CREATE INDEX idx ON t (v) USING GIN('parser' = 'english');
全文倒排索引的基本语法如下所示。
INDEX <index name>(<column name>) USING GIN(properties)
涉及参数如下所示。
参数
说明
<index_name>
自定义的索引名称。
<column_name>
需要创建索引的列名。
USING GIN
指定索引类型为GIN(Generalized Inverted Index),即倒排索引。
properties
索引的配置参数,通常以键值对的形式提供。支持以下属性:
parser
:用于指定分词的方式。支持的值如下:none
:默认值,表示不进行任何分词操作。english
:使用CLucene的Simple Analyzer进行分词,适用于英文文本的分词,并且不区分大小写。chinese
:使用CLucene的CJK Analyzer进行分词,适用中文分词。standard
:使用CLucene的Standard Analyzer进行分词,适用于大多数分词方式,并且不区分大小写。
omit_term_freq_and_position
:用于指定在构建倒排索引时是否忽略词频和词的位置,以降低存储使用。默认为false,设置为true时不支持匹配短语(MATCH_PHRASE)。
查看全文倒排索引
执行以下命令,查看全文倒排索引。
SHOW CREATE TABLE testdb.`t`;
在输出结果区域,右键并预览Create Table列的信息。
本文示例展示以下信息。
CREATE TABLE `t` ( `k` bigint(20) NOT NULL COMMENT "", `v` varchar(65533) NULL COMMENT "", INDEX idx (`v`) USING GIN("parser" = "english") COMMENT '' ) ENGINE=OLAP DUPLICATE KEY(`k`) DISTRIBUTED BY HASH(`k`) BUCKETS 1 PROPERTIES ( "compression" = "LZ4", "fast_schema_evolution" = "true", "replicated_storage" = "false", "replication_num" = "3" );
删除全文倒排索引
通过
ALTER TABLE DROP INDEX
删除ALTER TABLE t DROP index idx;
通过
DROP INDEX
删除DROP INDEX idx on t;
使用全文倒排索引加速查询
在使用该功能之前,请确保已将enable_gin_filter
和enable_prune_column_after_index_filter
两个参数设置为true。如果未对这两个参数进行修改,那么默认值均为true。
如果全文倒排索引对索引列进行分词处理,即'parser' = 'standard|english|chinese'
,此时查询条件中仅支持使用谓词MATCH通过全文倒排索引进行数据过滤,且格式必须为<col_name> (NOT) MATCH '%keyword%'
。在此,keyword必须为字符串字面量,不支持使用表达式。
创建表示例
create database testdb;
CREATE TABLE testdb.`http_logs` (
`@timestamp` int(11) NULL COMMENT "",
`clientip` varchar(20) NULL COMMENT "",
`request` varchar(65533) NULL COMMENT "",
`status` int(11) NULL COMMENT "",
`size` int(11) NULL COMMENT "",
INDEX request_idx (`request`) USING GIN("parser" = "english") COMMENT ''
) ENGINE=OLAP
DUPLICATE KEY(`@timestamp`)
COMMENT "OLAP"
DISTRIBUTED BY RANDOM BUCKETS 1
PROPERTIES ("replicated_storage" = "false");
insert into testdb.http_logs values
('893964617','40.135.*.*','GET /images/hm_bg.jpg HTTP/1.0',200,24736),
('893964653','232.0.*.*','GET /images/hm_bg.jpg HTTP/1.0',200,24736),
('893964672','26.1.*.*','GET /images/hm_bg.jpg HTTP/1.0',200,24736),
('893964679','247.37.*.*','GET /french/splash_inet.html HTTP/1.0',200,3781),
('893964682','247.37.*.*','GET /images/hm_nbg.jpg HTTP/1.0',304,0),
('893964687','252.37.*.0','GET /images/hm_bg.jpg HTTP/1.0',200,24736),
('893964689','247.37.*.*','GET /images/hm_brdl.gif HTTP/1.0',304,0),
('893964689','247.37.*.*','GET /images/hm_arw.gif HTTP/1.0',304,0),
('893964692','247.37.*.*','GET /images/nav_bg_top.gif HTTP/1.0',200,929),
('893964703','247.37.*.*','GET /french/images/nav_venue_off.gif HTTP/1.0',304,0);
支持的查询方式
StarRocks提供了多种基于全文倒排索引的查询方式,适用于不同的场景:
MATCH/MATCH_ANY
语义:只要与拆分后的任意一个词项(
term
)匹配即可。示例
select * from testdb.http_logs where request match "images hm_bg";
返回信息如下所示。
MATCH_ALL
语义:所有拆分后的
term
必须全部匹配。示例
select * from testdb.http_logs where request match_all "images hm_bg";
返回信息如下所示。
MATCH_PHRASE
语义:短语匹配。要求所给查询的所有解析后的词项均需匹配,并且这些词项的位置必须与文档中的对应位置一致,方可成立匹配关系。
示例
select * from testdb.http_logs where request match_phrase "GET /images";
返回信息如下所示。
MATCH_PHRASE_PREFIX
语义:前缀匹配。匹配所有以给定查询作为前缀的字段。
示例
select * from testdb.http_logs where request match_phrase_prefix "GET /im";
返回信息如下所示。
MATCH_PHRASE_EDGE
语义:复杂匹配模式,支持前后缀匹配和中间项匹配。
如果给出的查询可以拆分为两个或以上的词项,则第一个词项作为后缀进行匹配,最后一个词项作为前缀进行匹配,中间的所有词项共同参与匹配。仅当所有词项均匹配时,才能认为匹配成功。
示例
select * from testdb.http_logs where request match_phrase_edge 'et images hm';
返回信息如下所示。
调试与验证倒排索引
使用tokenize函数验证分词器行为
为了确保全文倒排索引的行为符合预期,StarRocks提供了tokenize
函数,用于模拟分词器的行为并验证分词结果。该函数可以帮助用户检查分词器是否正确处理了输入数据,从而优化查询条件。
tokenize("<parser_type>", "<input_strings>");
参数说明:
<parser_type>
:分词器类型,与倒排索引支持的parser
一致。<input_strings>
:需要分词的字符串或列名。
返回值:返回一个数组(
ARRAY
类型),数组中的每个元素是一个分词后的单词或term
。
示例用法
验证分词器行为
在创建倒排索引之前,可以通过
tokenize
函数测试分词器的行为,确保分词结果符合预期。SELECT tokenize("english", "GET /images/hm_bg.jpg HTTP/1.0");
返回结果如下所示。
["get","images","hm","bg","jpg","http","1","0"]
调试查询结果
如果查询结果不符合预期,可以通过
tokenize
函数检查分词器是否正确处理了输入数据。假设表
http_logs
的列request
包含以下数据。GET /images/hm_bg.jpg HTTP/1.0 GET /french/splash_inet.html HTTP/1.0
使用
tokenize
验证分词结果。SELECT tokenize("english", request) FROM http_logs;
返回信息如下所示。
["get","images","hm","bg","jpg","http","1","0"] ["get","french","images","nav","venue","off","gif","http","1","0"]
动态分词处理
在查询中直接对列内容进行分词处理,适合临时分析或调试场景,尤其是在未创建倒排索引时快速查看分词结果。
SELECT `@timestamp`, tokenize("english", request) AS tokens FROM testdb.http_logs;