最近更新时间:2024.04.18 15:30:57
首次发布时间:2024.04.18 15:30:57
全文检索(或仅文本搜索)提供了识别满足查询的自然语言文档的功能。最常见的搜索类型是查找包含给定查询词的所有文档。全文索引允许对文档进行预处理并保存索引以供以后快速搜索。我们通过增加文本倒排索引的能力,来支持更快速的文本检索和过滤的方式。
ByteHouse 云数仓版支持通过 SQL 语法来进行全文检索,本文将介绍如何创建全文索引并进行查询。
目前全文检索支持根据三种文本分词索引方式:
创建全文检索的基本语法举例如下,根据索引方式的不同,我们需要为inverted()中设置不同的值。
CREATE TABLE tab ( `key` UInt64, `str` String, INDEX inv_idx(str) TYPE inverted(0) GRANULARITY 1 ) ENGINE = CnchMergeTree ORDER BY key SETTINGS index_granularity = 1024;
设置inverted(0)
或者inverted()
时,分词器将设置为“tokens”,即沿空格分割字符串。
CREATE TABLE test_inverted_with_token ( `key` UInt64, `doc` String, -- low(doc) 只将 英文字母 转换为 小写后进行文本处理 -- -- 在不特殊指定时默认采用 Token 进行分词 -- INDEX doc_idx lower(doc) TYPE inverted GRANULARITY 1 ) ENGINE = CnchMergeTree() ORDER BY key SETTINGS index_granularity = 1024;
设置为inverted(N)
时,即是使用 N-gram 分词器,范围为[ 2 , 8 ]。
CREATE TABLE test_inverted_with_ngram ( `key` UInt64, `doc` String, -- low(doc) 只将 英文字母 转换为 小写后进行文本处理 -- -- 指定数字 N 代表采用 N-gram 对文本分词 -- INDEX doc_idx lower(doc) TYPE inverted(4) GRANULARITY 1 ) ENGINE = CnchMergeTree() ORDER BY key SETTINGS index_granularity = 1024;
ByteHouse 云数仓版可以通过默认配置的词库进行中文文本索引。
CREATE TABLE test_gin.ch_docs ( `key` UInt64, `doc` String, -- token_chinese_default 代表使用token_chinese_default分词器-- -- default 代表使用default配置 -- -- 代表分词密度范围是 范围是(0 - 1.0],会对频率高的分词忽略处理-- INDEX inv_idx doc TYPE inverted('token_chinese_default', 'default',1.0) GRANULARITY 1 ) ENGINE = CnchMergeTree ORDER BY key SETTINGS index_granularity = 1024;
数据库中包含某中文作品数据,通过 ngram + 中文分词 的方式建表导入测试。
-- 原表
CREATE TABLE test_gin.ch_docs
(row
UInt64,doc
String
)
ENGINE = CnchMergeTree
ORDER BY row
SETTINGS index_granularity = 1024;
insert into test_gin.ch_docs format CSVWithNames infile '/home/caichangheng/some1.csv';
0 rows in set. Elapsed: 0.944 sec. Processed 50.23 thousand rows, 7.65 MB (53.20 thousand rows/s., 8.11 MB/s.)
--中文分词表
CREATE TABLE test_gin.ch_docs_ch
(row
UInt64,doc
String,
INDEX inv_idx doc TYPE inverted('token_chinese_default', 'default', 1.0) GRANULARITY 1
)
ENGINE = CnchMergeTree
ORDER BY row
SETTINGS index_granularity = 1024;
insert into test_gin.ch_docs_ch format CSVWithNames infile '/home/caichangheng/some1.csv';
0 rows in set. Elapsed: 41.191 sec. Processed 50.23 thousand rows, 7.65 MB (1.22 thousand rows/s., 185.81 KB/s.)
-- 2-gram 分词表
CREATE TABLE test_gin.ch_docs_ngram
(row
UInt64,doc
String,
INDEX inv_idx doc TYPE inverted(2) GRANULARITY 1
)
ENGINE = CnchMergeTree
ORDER BY row
SETTINGS index_granularity = 1024;
insert into test_gin.ch_docs_ngram format CSVWithNames infile '/home/caichangheng/some1.csv';
0 rows in set. Elapsed: 17.109 sec. Processed 50.23 thousand rows, 7.65 MB (2.94 thousand rows/s., 447.34 KB/s.)
查询语句如下: ```SQL select count() from test_gin.ch_docs where doc like '%山东%'; select count() from test_gin.ch_docs_ch where doc like '%山东%'; select count() from test_gin.ch_docs_ngram where doc like '%山东%'; select count() from test_gin.ch_docs where doc like '%溥仪%'; select count() from test_gin.ch_docs_ch where doc like '%溥仪%'; select count() from test_gin.ch_docs_ngram where doc like '%溥仪%';
目前文本检索表达式支持( ) & | !
这五个基本逻辑运算符。
全文检索表达式不参与算子的计算,直接在倒排列表行级过滤当中进行过滤。
注意
目前 textSearch 只支持与其他运算符做 AND 交集操作,不适合做 NOT 和 OR 操作。
使用举例
select * from test_inverted where textSearch(doc, '查询'); select * from test_inverted where textSearch(doc, '查询 | 数仓'); select * from test_inverted where textSearch(doc, '查询 & 即席'); select * from test_inverted where textSearch(doc, '查询 & !即席'); select * from test_inverted where textSearch(doc, '查询 & !复杂 & ( 交互 | 擅长) | 数仓 & !数仓');