全文检索(或仅文本搜索)提供了识别满足查询的自然语言文档的功能。最常见的搜索类型是查找包含给定查询词的所有文档。全文索引允许对文档进行预处理并保存索引以供以后快速搜索。我们通过增加文本倒排索引的能力,来支持更快速的文本检索和过滤的方式。
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; --加入全文索引 ALTER TABLE {table_name} ADD INDEX {index_name} {column_to_index} TYPE {index_type_and_arguments} GRANULARITY {index_granularity}; --加入物化索引 ALTER TABLE {table_name} MATERIALIZE INDEX {index_name}; -- 删除索引 ALTER TABLE {table_name} DROP INDEX {index_name}; ALTER TABLE {table_name} CLEAR INDEX {index_name};
设置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.)
查询语句如下:
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 '%溥仪%';