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

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

索引方式

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

  • 语言Token分词:Token分词以 空格标点符号 进行分词处理,通常适用于英语等有明显的以空格标点分词的语言种类。
  • Ngram分词:Ngram分词遇到 指定的字符(如 : 空白、标点)时分割文本,然后返回指定长度的每个单词的 N-grams。通常用于查询不使用空格或具有较长复合词的语言。

语法

基本语法

创建全文检索的基本语法举例如下,根据索引方式的不同,我们需要为inverted()中设置不同的值。

--建表时创建索引
CREATE TABLE table_with_ivt_idx
(
    key UInt64,  
    str String,
    INDEX inv_idx(str) TYPE inverted() GRANULARITY 1
)
ENGINE = CnchMergeTree
ORDER BY key;

--建表后增加索引
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) 只将 英文字母 转换为 小写后进行文本处理
    INDEX doc_idx lower(doc) TYPE inverted GRANULARITY 1 -- 在不特殊指定时默认采用 Token 进行分词
)
ENGINE = CnchMergeTree()
ORDER BY key;

Ngram分词

设置为inverted(N) 时,即是使用 N-gram 分词器,范围为[ 2 , 8 ]。

CREATE TABLE test_inverted_with_ngram
(
    key UInt64,
    doc String,-- low(doc) 只将 英文字母 转换为 小写后进行文本处理
    INDEX doc_idx lower(doc) TYPE inverted(4) GRANULARITY 1-- 指定数字 4 代表采用 4-gram 对文本分词
)
ENGINE = CnchMergeTree()
ORDER BY key;

使用举例

数据库中包含某中文作品数据,通过 ngram 的方式建表导入测试。

-- 原表
CREATE TABLE test_gin.ch_docs
(
    row UInt64,    
    doc String
)
ENGINE = CnchMergeTree
ORDER BY row;

insert into test_gin.ch_docs format CSVWithNames infile '/home/user/sample.csv';

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

insert into test_gin.ch_docs_ngram format CSVWithNames infile '/home/user/sample.csv';

查询语句如下:

select count() from test_gin.ch_docs 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_ngram where doc like '%云计算%';

查询函数

String类型

函数名

描述

equals

检查字段值是否等于指定值。

notEquals

检查字段值是否不等于指定值。

like

检查字段值是否匹配指定模式。

notLike

检查字段值是否不匹配指定模式。

hasToken

检查字段值是否包含指定令牌。

startsWith

检查字段值是否以指定前缀开头。

endsWith

检查字段值是否以指定后缀结尾。

multiSearchany

对字段的任意值使用指定的搜索词进行多搜索。

notIn

检查字段值是否不在指定值列表中。

in

检查字段值是否在指定值列表中。

Array String 类型

函数名

功能描述

has

判断一个元素是否在给定的数组或集合中

hasAny

判断给定的数组或集合中是否至少有一个元素满足指定的条件

arraySetCheck

检查一个数组或集合是否满足指定的条件