You need to enable JavaScript to run this app.
导航

全文检索

最近更新时间2024.04.18 15:30:57

首次发布时间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;

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 + 中文分词 的方式建表导入测试。

```SQL

-- 原表
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, '查询 & !复杂 &  ( 交互 | 擅长) | 数仓 & !数仓');