You need to enable JavaScript to run this app.
导航
全文检索
最近更新时间:2024.05.30 15:35:30首次发布时间:2024.04.18 15:30:57

全文检索(或仅文本搜索)提供了识别满足查询的自然语言文档的功能。最常见的搜索类型是查找包含给定查询词的所有文档。全文索引允许对文档进行预处理并保存索引以供以后快速搜索。我们通过增加文本倒排索引的能力,来支持更快速的文本检索和过滤的方式。
ByteHouse 云数仓版支持通过 SQL 语法来进行全文检索,本文将介绍如何创建全文索引并进行查询。

索引方式

目前全文检索支持根据三种文本分词索引方式:

  • 语言Token分词:Token分词以 空格标点符号 进行分词处理,通常适用于英语等有明显的以空格标点分词的语言种类。
  • Ngram分词:Ngram分词遇到 指定的字符(如 : 空白、标点)时分割文本,然后返回指定长度的每个单词的 N-grams。通常用于查询不使用空格或具有较长复合词的语言。
  • 中文分词:中文分词利用统计模型 隐式马尔科夫模型 来对中文进行分词。用户可以灵活配置模型和分词词典。

语法

基本语法

创建全文检索的基本语法举例如下,根据索引方式的不同,我们需要为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};

Token分词

设置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;

Ngram分词

设置为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 '%溥仪%';

查询语句