# 全文搜索

注意

本指南仅适用于DB版本1.5.0或更高版本。

多年来,具有LIKEILIKE等运算符的传统数据库文本搜索功能一直是基础。然而,由于几个限制,它们无法满足现代信息检索系统的需求:

  • 缺乏语言支持: 传统方法在处理语言细微差别时存在困难,无法识别单词派生(例如,“satisfies”与“satisfy”),这可能导致搜索结果不完整或不准确。虽然可以使用OR手动搜索变体,但这种方法繁琐且容易出错。
  • 缺乏结果排序: 没有结果排序的能力,浏览成千上万个匹配项变得低效。
  • 性能问题: 缺乏索引支持意味着每次搜索都必须处理每个文档,导致性能缓慢。

为了克服这些挑战,MyScale引入了一种名为FTS索引(全文搜索索引)的新索引类型,由Tantivy (opens new window)库提供支持,这是一个高性能的开源全文搜索引擎库。FTS索引支持BM25索引算法,实现了高效和相关的搜索结果。这种集成增强了MyScale的全文搜索功能,并提高了整体性能。

# 教程概述

本教程将指导您进行三种类型的FTS索引搜索实验:

MyScale中的FTS索引示例

在开始之前,请确保您已经设置了一个MyScale集群。有关设置说明,请参阅我们的快速入门指南 (opens new window)

# 数据集概述

我们将使用Wikipedia摘要数据集 (opens new window),其中包含超过560万条记录,以Parquet格式提供。此数据集将直接从S3导入到MyScale中,无需本地下载。

下表简要描述了此数据集的内容。

id body title url
... ... ... ...
77 Jake Rodkin is an American .... and Puzzle Agent. Jake Rodkin https://en.wikipedia.org/wiki/Jake_Rodkin (opens new window)
78 Friedlandpreis der Heimkehrer is ... of Germany. Friedlandpreis der Heimkehrer https://en.wikipedia.org/wiki/Friedlandpreis_der_Heimkehrer (opens new window)
... ... ... ...

# 创建和填充表

使用以下SQL命令在MyScale中创建en_wiki_abstract表:

CREATE TABLE default.en_wiki_abstract(
    `id` UInt64,
    `body` String,
    `title` String,
    `url` String,
)
ENGINE = MergeTree
ORDER BY id;

然后,从S3导入数据集。请耐心等待数据导入完成。

INSERT INTO default.en_wiki_abstract SELECT * FROM s3('https://myscale-datasets.s3.ap-southeast-1.amazonaws.com/wiki_abstract_5m.parquet','Parquet');

验证表中包含5648453行数据。

SELECT count(*) FROM default.en_wiki_abstract;

输出:

count()
5648453

为了提高搜索性能,我们可以通过将其合并为单个数据部分来优化表。这一步是可选的。

OPTIMIZE TABLE default.en_wiki_abstract FINAL;

运行以下SQL语句检查此表中的数据是否已压缩为一个部分。

SELECT COUNT(*) FROM system.parts
WHERE table = 'en_wiki_abstract' AND active = 1;

如果数据压缩为1,则此SQL语句将返回以下结果集:

count()
1

# 理解FTS索引参数

MyScale支持各种分词器,每个分词器适用于不同的场景。在创建FTS索引时,您可以使用JSON配置为分词器自定义索引。

提示

请在FTS索引的参数中提供有效的JSON字符串。

-- 示例1:创建一个没有指定参数的索引,使用默认配置
ALTER TABLE [table_name] ADD INDEX [index_name] [column_name]
TYPE fts;
-- 示例2:使用默认分词器创建索引
ALTER TABLE [table_name] ADD INDEX [index_name] [column_name]
TYPE fts('{"<column_name>":{"tokenizer":{"type":"default"}}}');
-- 示例3:使用stem分词器并应用停用词
ALTER TABLE [table_name] ADD INDEX [index_name] [column_name]
TYPE fts('{"<column_name>":{"tokenizer":{"type":"stem", "stop_word_filters":["english"]}}}');

下表列出了FTS索引支持的分词器类型。

分词器类型 描述
default 默认分词器,按非字母字符拆分文本,不区分大小写
raw 原始分词器,在文本上不进行分词处理,将整个文本视为单个标记
simple 简单分词器,按非字母字符拆分文本
stem 词干分词器,支持多种语言,将单词转换为其词干形式,可以忽略单词时态
whitespace 空格分词器,按空格字符(空格、制表符、换行等)拆分文本
ngram N-gram分词器,根据指定的n-gram长度拆分文本
chinese 中文分词器,对中文文本进行分词处理,内部使用jieba分词库进行分词

# 常见分词器参数

rawstem分词器仅支持store_doc参数,其他分词器除了支持上述常见参数外,还支持以下常见参数。

参数名称 类型 默认值 描述
store_doc 布尔值 false 是否存储原始文档,目前不建议启用
length_limit 数字 40 分词标记的最大长度
case_sensitive 布尔值 false 分词是否区分大小写

除了上述常见参数外,大多数分词器还支持其他参数。

# simplestemwhitespace分词器

参数名称 类型 默认值 描述
stop_word_filters 字符串数组 [] 停用词过滤器,指定在分词过程中要丢弃的停用词的语言,所有有效的语言包括["danish", "dutch", "english", "finnish", "french", "german", "hungarian", "italian", "norwegian", "portuguese", "russian", "spanish", "swedish"]

# stem分词器

参数名称 类型 默认值 描述
stem_languages 字符串数组 [] 用于词干提取的语言,对于英语,它可以在分词过程中忽略单词时态,stem分词器支持的语言有["arabic", "danish", "dutch", "english", "finnish", "french", "german", "greek", "hungarian", "italian", "norwegian", "portuguese", "romanian", "russian", "spanish", "swedish", "tamil", "turkish"]

# ngram分词器

参数名称 类型 默认值 描述
min_gram 数字 2 最小n-gram数量
max_gram 数字 3 最大n-gram数量
prefix_only 布尔值 false 是否仅从单词前缀提取n-gram

# chinese分词器

对于中文分词器,使用cang-jie (opens new window)作为底层实现。

参数名称 类型 默认值 描述
jieba 字符串 "default" "default"表示使用jieba字典,"empty"表示不使用内置的jieba字典进行分词。有效值为"default""empty"
mode 字符串 "search" 中文分词模式,有效值为"all"、"default"、"search"或"unicode",每种模式之间的区别可以参考cang-jie/options.rs (opens new window)
hmm 布尔值 false 是否启用HMM

上述提供了MyScale FTS索引分词器参数的详细描述。在创建FTS索引时,您可以选择最适合您需求的分词器类型,并配置其参数以提高搜索性能和结果。

# 创建FTS索引

使用适当的分词器自定义您的FTS索引以优化搜索性能。例如,使用带有英语停用词的stem分词器可以通过关注单词的根形式来提高搜索准确性。

ALTER TABLE default.en_wiki_abstract
ADD INDEX body_idx (body)
TYPE fts('{"body":{"tokenizer":{"type":"stem", "stop_word_filters":["english"]}}}');

通常情况下,FTS索引(类似于ClickHouse中的跳过索引)仅适用于新插入的数据,因此仅添加索引不会影响现有数据。要对已存在的数据进行索引,请使用以下语句:

ALTER TABLE default.en_wiki_abstract MATERIALIZE INDEX body_idx;

# 使用文档BM25排序进行搜索

注意

首次执行TextSearch()可能会较慢,因为它需要加载FTS索引。

以下示例演示了如何使用TextSearch()函数。该示例返回与“non-profit institute in Washington”相关的前10个最相关文档。衡量相关性的指标是TextSearch()函数返回的BM25分数,分数越高,相关性越高。

SELECT
    id,
    title,
    body,
    TextSearch(body, 'non-profit institute in Washington') AS score
FROM default.en_wiki_abstract
ORDER BY score DESC
LIMIT 5;

从结果中,我们可以看到每行body列中的文本与搜索短语“non-profit institute in Washington”相关。

id title body score
3400768 Drug Strategies Drug Strategies is a non-profit research institute located in Washington D.C. 24.457561
872513 Earth Policy Institute Earth Policy Institute was an independent non-profit environmental organization based in Washington, D.C. 22.730673
895248 Arab American Institute Founded in 1985, the Arab American Institute is a non-profit membership organization based in Washington D.C. 21.955559
1950599 Environmental Law Institute The Environmental Law Institute (ELI) is a non-profit, non-partisan organization, headquartered in Washington, D.C. 21.231567
2351478 Public Knowledge Public Knowledge is a non-profit Washington, D.C. 20.742344

# 利用自然语言查询

MyScale使用Tantivy库进行全文搜索(FTS)索引,支持复杂的自然语言查询。有关详细信息,请参阅Tantivy的文档 (opens new window)

下面是一个使用ANDOR进行多条件组合查询的示例。我们想要搜索与纽约市、非洲或巴黎相关的人类学主题。SQL查询如下:

SELECT
    id,
    title,
    body,
    TextSearch(body, 'Anthropological AND ("New York City" OR African OR Paris)') AS score
FROM default.en_wiki_abstract
ORDER BY score DESC
LIMIT 5;

搜索结果显示,每行文本都包含左侧AND语句中的条件“Anthropological”,同时每个结果至少包含右侧AND语句中的一个条件“African”、“New York City”或“Paris”。

id title body score
2826913 African Anthropologist African Anthropologist is the journal of the Pan African Anthropological Association (PAAA). 20.131313
3905943 Tunnel People Tunnel People is an anthropological-journalistic account describing an underground homeless community in New York City. It is written by war photographer and anthropologist Teun Voeten and was published by PM Press in 2010. 13.759308
3790627 Les Accords de Bella Les Accords de Bella is a 2007 anthropological documentary film directed by David Constantin. It was selected by the African Film Festival of Cordoba - FCAT. 12.769518
4488199 Naparay Naparay, in African anthropological study, is a non-linear conception of human life held by some West African peoples such as the Yoruba. Similar to reincarnation, naparay holds that lives are cyclic and attributes of previous lives may carry over to a new life. 11.682068
1725559 Gradhiva Gradhiva is an anthropological and museological journal, founded in 1986 by the poet and social scientist Michel Leiris and by the anthropologist Jean Jamin. It is since 2005 published by the Musée du Quai Branly in Paris. 11.135916

# TextSearch参数解释

注意

参数仅适用于DB版本v1.6.3或更高版本。

以下是TextSearch()参数的详细说明:

参数 默认值 候选值 描述
enable_nlq true true, false 此参数决定是否启用自然语言查询解析。当设置为true时,FTS将将用户输入解释为自然语言查询。当设置为false时,FTS将使用标准术语查询解析用户输入。
operator OR OR, AND 此参数指定用于组合每个查询条件(由分词器标记化)的逻辑运算符。选择OR将返回与任何条件匹配的结果,而选择AND将返回与所有条件匹配的结果。

# 示例用法

SELECT
    id,
    title,
    body,
    TextSearch('enable_nlq=true', 'operator=OR')(body, 'mammoth AND Europe') AS score
FROM default.wiki_abstract_text
ORDER BY score DESC
LIMIT 5

基于结果,每行都包含“mammoth”和“Europe”,符合启用自然语言查询的逻辑。

请注意,只有2个搜索结果。尽管我们的SQL查询将限制设置为5,但只有2个表中的条目符合条件。

id title body score
3171491 Leymus racemosus Leymus racemosus is a species of perennial wild rye known by the common name mammoth wild rye. It is native to southeastern and eastern Europe, Middle Asia, Caucasus, Siberia, China, Mongolia, New Zealand, and parts of North America. 10.067189
2719784 Venus of Hohle Fels The Venus of Hohle Fels (also known as the Venus of Schelklingen; in German variously ) is an Upper Paleolithic Venus figurine made of mammoth ivory that was unearthed in 2008 in Hohle Fels, a cave near Schelklingen, Germany. It is dated to between 35,000 and 40,000 years ago, belonging to the early Aurignacian, at the very beginning of the Upper Paleolithic, which is associated with the earliest presence of Cro-Magnon in Europe. 6.9371195
SELECT
    id,
    title,
    body,
    TextSearch('enable_nlq=false', 'operator=OR')(body, 'Atlantic AND Europe') AS score
FROM default.wiki_abstract_text
ORDER BY score DESC
LIMIT 5

在禁用自然语言查询后,结果不再保证同时出现“Atlantic”和“Europe”。由于运算符的默认值是OR,任何包含“Atlantic”、“AND”或“Europe”的行都将包含在搜索结果中。

id title body score
3046233 And And or AND may refer to: 13.748591
5050203 A N D (Tricot album) And}} 13.047318
357499 Andromeda I And 1}} 12.335348
678064 Omicron Andromedae And 1}} 12.335348
3716928 Platycheirus ramsaerensis Platycheirus ramsaerensis is a species of hoverfly. It is found along the parts of northern Europe that face the Atlantic. 11.937536

# 利用SkipIndex进行字符串搜索

当使用以下ClickHouse内置函数进行字符串搜索时,它们都将通过FTS索引进行过滤:equalsnotEqualslikenotLikehasTokenhasTokenOrNullinnotInstartsWithendsWithhasmapContainsmultiSearchAny

示例1 - 执行简单的关键字搜索,例如搜索单词'Tsinghua'。

SELECT count(*)
FROM default.en_wiki_abstract
WHERE hasToken(body, 'Tsinghua');

输出:

count()
81

示例2 - 执行多关键字搜索,查找包含Eiffel Tower但不包含Paris的文章。

SELECT count(*)
FROM default.en_wiki_abstract
WHERE (NOT hasToken(body, 'Paris')) AND multiSearchAny(body, ['Eiffel', 'Tower'])

输出:

count()
2828

示例3 - 执行复杂的条件组合查询,结合不同的名称、地点、学科和其他术语。

SELECT count(*)
FROM default.en_wiki_abstract
WHERE (NOT multiSearchAny(body, ['Montessori', 'postulated', 'Rooney'])) AND (hasToken(body, 'Patsy') OR hasToken(body, 'Anthropological'))

输出:

count()
204

# 结论

本指南介绍了如何利用MyScale进行高级文本搜索功能,从设置FTS索引到执行自然语言查询。通过应用这些技术,您可以高效地管理和搜索非结构化文本数据,展示了MyScale强大的文本处理能力。

Last Updated: Sun Jun 30 2024 09:15:57 GMT+0000