引言
全文检索是PostgreSQL中一项非常强大的功能,它能够对文本数据进行高效的全文搜索,提供灵活的搜索方式和强大的搜索能力,广泛应用于搜索引擎、内容管理、电子商务等领域。
什么是全文检索?
全文检索是一种基于文本数据的搜索技术,它通过对文本内容进行分析和处理,建立索引,并支持用户进行高效的全文搜索。与传统数据库搜索相比,全文检索更加注重对于文本内容的处理和搜索,能够更好地支持自然语言搜索和模糊搜索,提供更加丰富的搜索方式和结果。
全文检索需要什么?
选择搜索模块
在PostgreSQL中,实现全文检索需要使用一些特殊的工具和模块,其中最常用的是tsearch2模块。tsearch2模块是PostgreSQL的一个扩展模块,它提供了全文检索相关的功能,包括文本分析、索引创建和查询执行等。
PostgreSQL 全文检索可以通过两个主要的模块来实现:tsearch2 和 OpenFTS。下面我将简要介绍这两种方法:
-
tsearch2 模块:
tsearch2是 PostgreSQL 的一个全文检索模块,它提供了用于全文搜索的一组函数和运算符。可以使用这个模块来创建全文搜索索引,执行全文搜索查询并获得相关性排序的结果。使用
tsearch2进行全文检索通常涉及以下步骤:- 安装和启用
tsearch2模块。 - 在需要进行全文搜索的表上创建全文搜索索引。
- 编写全文搜索查询,使用
to_tsquery函数将查询转换为适当的 tsquery 数据类型,并使用ts_rank函数来计算结果的相关性分数。
这是一个简单的示例:
-- 创建全文搜索索引 CREATE INDEX idx_text_search ON your_table USING gin(your_column gin_trgm_ops); -- 执行全文搜索查询 SELECT * FROM your_table WHERE your_column @@ to_tsquery('search term') ORDER BY ts_rank(your_column, to_tsquery('search term')) DESC; - 安装和启用
-
OpenFTS 模块:
OpenFTS(Open Full-Text Search)是一个用于 PostgreSQL 的开源全文搜索模块,它提供了更高级的全文搜索功能,支持多种语言和高级查询操作。使用
OpenFTS进行全文检索通常涉及以下步骤:- 安装和启用
OpenFTS模块。 - 在需要进行全文搜索的表上创建全文搜索索引。
- 使用
fts函数执行全文搜索查询,该函数支持更复杂的查询操作。
这是一个简单的示例:
-- 创建全文搜索索引 CREATE INDEX idx_text_search ON your_table USING gist(your_column gist_fts_ops); -- 执行全文搜索查询 SELECT * FROM your_table WHERE fts(your_column, 'search term'); - 安装和启用
要选择使用哪种全文搜索方法,取决于您的需求和数据库架构。通常情况下,如果需要更高级的全文搜索功能和多语言支持,OpenFTS 可能是更好的选择。如果只需基本的全文搜索功能,tsearch2 足够。
设置FTS(full-text-search)配置
PostgreSQL全文检索是通过FTS配置库来支持的,配置用于定义全文搜索引擎的行为和规则,以便在文本数据上执行高效的全文搜索操作。FTS 配置允许你指定如何分析文本、处理停用词、定义词干提取规则等。自带来10个以上的FTS配置库
可以通过psql的\dF命令来查看已经安装的配置库
以下是 FTS 配置的主要作用:
-
文本分析:FTS 配置允许你定义如何分析文本数据。这包括如何将文本分解为单词或词汇单元,如何处理标点符号和特殊字符,以及如何处理大小写等。配置可以根据不同的语言或文本类型进行调整,以适应不同的文本分析需求。
-
停用词处理:停用词是在全文搜索中通常会被忽略的常见词汇,如 "the"、"and"、"is" 等。FTS 配置可以定义哪些词汇应该被视为停用词,以便不纳入搜索索引或搜索查询中,从而提高搜索结果的相关性。
-
词干提取:词干提取是将词汇转化为其基本形式或词根的过程。FTS 配置可以定义如何执行词干提取,以便搜索引擎能够识别相关词汇的变化形式并将它们视为相同的词汇。这有助于扩展搜索的覆盖范围。
-
同义词处理:FTS 配置可以定义同义词映射,以将不同词汇映射到相同的搜索词汇。这有助于扩展搜索的范围,并确保用户可以找到相关的结果,即使他们使用不同的词汇。
-
配置关联:FTS 配置可以与全文搜索索引关联,以确定哪个配置应该在索引创建和搜索查询中使用。这允许你在不同的搜索任务中使用不同的配置,以获得最佳的搜索性能和结果。
-
搜索结果排序:FTS 配置还可以影响搜索结果的排序。不同的配置可以定义不同的搜索权重,以便将最相关的结果排在前面。
总之,FTS 配置在 PostgreSQL 的全文搜索中起着关键作用,它允许你根据你的需求和数据类型来自定义全文搜索引擎的行为,以提供更准确、相关性更高的搜索结果。通过合理配置 FTS,你可以使搜索引擎更好地适应不同的应用场景和文本数据。
在 PostgreSQL 的全文搜索(FTS)中,不同的 FTS 配置用于定义全文搜索引擎的不同行为和规则。每个 FTS 配置都可以适用于不同的搜索需求和文本数据类型。以下是一些常见的 FTS 配置及其作用:
-
simple配置:- 作用:
simple配置是 PostgreSQL 默认的全文搜索配置。它执行基本的文本分析,将文本拆分为单词并将它们小写化。它不执行停用词处理、词干提取或同义词处理。 - 适用场景:适用于简单的文本搜索任务,不需要高级文本处理。
- 作用:
-
english配置:- 作用:
english配置适用于英语文本。它执行英语停用词处理、词干提取和同义词处理,以提供更准确的搜索结果。 - 适用场景:适用于英语文本的搜索任务,特别是处理常见的英语停用词和复数形式。
- 作用:
-
german配置:- 作用:
german配置适用于德语文本。它执行德语停用词处理、词干提取和同义词处理,以提供更准确的搜索结果。 - 适用场景:适用于德语文本的搜索任务,特别是处理德语的复杂语法和构词法。
- 作用:
-
french配置:- 作用:
french配置适用于法语文本。它执行法语停用词处理、词干提取和同义词处理。 - 适用场景:适用于法语文本的搜索任务,特别是处理法语的特殊字符和词汇形式。
- 作用:
-
自定义配置:
- 作用:你可以创建自定义 FTS 配置,根据特定领域、应用程序或文本类型的需求定义文本分析、停用词处理、词干提取和同义词处理规则。自定义配置允许你更灵活地适应不同的文本数据和搜索需求。
- 适用场景:适用于特定领域或应用程序的搜索任务,需要定制化的文本处理。
每个配置都具有不同的文本处理规则,因此选择适合你的数据和需求的配置非常重要。你可以通过使用 ALTER TEXT SEARCH CONFIGURATION 命令来创建自定义配置,以及通过 ALTER MAPPING 命令将配置与自定义词典关联,以实现不同的文本分析和处理需求。根据你的应用程序和文本数据的特点,选择合适的 FTS 配置可以显著提高全文搜索的准确性和性能。
如何使用全文检索?
构建文本对应的索引
1 文本向量化
原始文本在构建索引之前需要被向量化,原始文本必须在被向量化后才能通过FTS 对其检索,该向量的数据类型是 tsvector。
PostgreSQL 提供to_tsvercor函数来将原始文本向量化:
select * from to_tsvector('To Be Number One!')
tsvector是有(词,序列)元组组成的列表。
2、创建全文索引 创建索引时,需要选择要进行分析和索引的列,并指定使用的文本分析方式和索引类型。这里我们以gin索引为例,配置为english。创建索引的方式有两种:
使用to_tsvector函数来创建gin索引
CREATE INDEX pgweb_idx ON pgweb USING GIN(to_tsvector('english', body));
单独增加一列字段类型为tsvector
ALTER TABLE pgweb ADD COLUMN textsearchable_index_col tsvector;
UPDATE pgweb SET textsearchable_index_col =
to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,''));
CREATE INDEX textsearch_idx ON pgweb USING GIN(textsearchable_index_col);
gin和gist的区别就是 gin查询更快, 但是构建速度可能会慢一点。 而 gist 的构建速度快, 查询会慢一点。
一般建议预计数据量不大时可以使用gist索引, 如果预计数据量很大请直接上gin。
通过搜索索引来找到对应的文本
PG的全文检索操作符是@@,当一个tsvector和tsquery匹配时返回true,并且前后顺序无影响。
使用to_tsquery函数将搜索关键词转换为tsquery格式,然后使用@@运算符进行搜索。查询条件可以使用布尔操作符&(AND)、|(OR)和!(NOT)来组合它们,还有短语搜索操作符<->(FOLLOWED BY)。
SELECT * FROM my_table WHERE to_tsvector(column_name) @@ to_tsquery('keyword');