关于全文搜索

本主题概述了Greenplum数据库全文搜索,基本文本搜索表达式,配置和自定义文本搜索。 以及Greenplum数据库全文搜索与Pivotal GPText的比较。

本节包含以下子主题:

全文搜索(或“文本搜索”)提供识别满足查询的自然语言文档的能力,并且有选择地通过与查询的相关性对它们进行排名。 最常见的搜索类型是查找包含给定查询字词的所有文档,并按照它们与查询的相似性的顺序返回它们。

Greenplum数据库提供了一个数据类型tsvector来存储预处理文档,以及一个数据类型tsquery来存储已处理的查询(全文搜索类型)。 这些数据类型有许多可用的函数和运算符(文本搜索函数和操作符),其中最重要的是匹配运算符@@,我们在基本文本匹配中介绍它们。 可以使用索引(文本搜索的GiST和GIN索引)加速全文搜索。

查询和相似性的概念非常灵活,取决于具体的应用。 最简单的搜索将查询视为一组单词和文档中查询单词出现频率的相似性。

Greenplum数据库支持文本数据类型的标准文本匹配运算符~,~*,LIKE和ILIKE,但这些运算符缺少搜索文档所需的许多基本属性:

  • 没有语言支持,即使是英语也是如此。 正则表达式是不够的,因为它们不能容易地处理派生词,例如satisfies和satisfy。 您可能会错过包含satisfies的文档,尽管您可能希望在搜索satisfy时找到它们。 可以使用OR来搜索多个派生形式,但这很繁琐且容易出错(有些词可能有几千种衍生词)。
  • 它们不提供搜索结果的排序(排名),这使得它们在找到数千个匹配文档时无效。

  • 它们往往很慢,因为没有索引支持,所以他们必须为每次搜索处理所有文档。

全文索引允许对文档进行预处理并保存索引以供以后快速搜索。 预处理包括:

  • 将文档解析为token。b> 识别各种类型的令牌(例如,数字,单词,复杂单词,电子邮件地址)是有用的,以便可以不同地处理它们。 原则上,令牌类取决于特定的应用程序,但是对于大多数用途来说,使用预定义的一组类就足够了。 Greenplum数据库使用解析器执行此步骤。 提供了标准解析器,可以根据特定需求创建自定义解析器。
  • 将token转换为词位。 词位是一个字符串,就像一个token,但它已被标准化,以便使相同单词的不同形式相似。 例如,规范化几乎总是包括将大写字母折叠成小写字母,并且通常涉及删除后缀(例如英语中的s或es)。 这允许搜索找到相同单词的变体形式,而无需繁琐地输入所有可能的变体。 此外,该步骤通常消除了停止词,这些词是如此常见以至于它们对搜索无用。 (简而言之,token是文档文本的原始片段,而词位是被认为对索引和搜索有用的词。) Greenplum数据库使用词典来执行此步骤。 提供各种标准词典,并且可以为特定需求创建自定义词典。
  • 存储为搜索而优化的预处理文档。 例如,每个文档可以表示为标准化词位的排序数组。 与词位一起,通常希望存储位置信息以用于邻近度排序,使得包含更“密集”的查询词区域的文档被分配比具有分散查询词的更高的等级。

字典允许对token如何标准化进行细粒度控制。 使用适当的词典,您可以:

  • 定义不应编入索引的停止词。
  • 使用Ispell将同义词映射到单个单词。
  • 使用同义词库将短语映射到单个单词。
  • 使用Ispell字典将单词的不同变体映射到规范形式。
  • 使用Snowball词干分析器规则将单词的不同变体映射到规范形式。

什么是文档

文档是在全文搜索系统中搜索的单位; 例如,杂志文章或电子邮件消息。 文本搜索引擎必须能够解析文档并存储与其父文档关联的词位(关键词)。 稍后,这些关联用于搜索包含查询词的文档。

对于Greenplum数据库中的搜索,文档通常是数据库表的行中的文本字段,或者可能是这些字段的组合(串联),可能存储在若干表中或动态获得。 换句话说,可以从不同的部分构造文档以进行索引,并且它可以不作为整体存储在任何地方。 例如:

  1. SELECT title || ' ' || author || ' ' || abstract || ' ' || body AS document
  2. FROM messages
  3. WHERE mid = 12;
  4. SELECT m.title || ' ' || m.author || ' ' || m.abstract || ' ' || d.body AS document
  5. FROM messages m, docs d
  6. WHERE mid = did AND mid = 12;

Note:

实际上,在这些示例查询中,应该使用coalesce来防止单个NULL属性导致整个文档的NULL结果。

另一种可能性是将文档作为简单文本文件存储在文件系统中。 在这种情况下,数据库可用于存储全文索引并执行搜索,并且一些唯一标识符可用于从文件系统检索文档。 但是,从数据库外部检索文件需要超级用户权限或特殊功能支持,因此这通常不如将所有数据保留在Greenplum数据库中。 此外,将所有内容保留在数据库中可以轻松访问文档元数据,以帮助索引和显示。

出于文本搜索的目的,每个文档必须简化为预处理的tsvector格式。 搜索和排名完全基于文档的tsvector表示执行 - 只有在选择文档以显示给用户时才需要检索原始文本。 因此,我们经常将tsvector称为文档,但当然它只是完整文档的紧凑表示。

基本文本匹配

Greenplum数据库中的全文搜索基于匹配运算符@@,如果tsvector(文档)与tsquery(查询)匹配,则返回true。 首先写入哪种数据类型无关紧要:

  1. SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & rat'::tsquery;
  2. ?column?
  3. ----------
  4. t
  5. SELECT 'fat & cow'::tsquery @@ 'a fat cat sat on a mat and ate a fat rat'::tsvector;
  6. ?column?
  7. ----------
  8. f

如上例所示,tsquery不仅仅是原始文本,也不仅仅是tsvector。 tsquery包含搜索项,它必须是已经规范化的词位,并且可以使用AND,OR和NOT运算符组合多个项。 (有关详细信息,请参阅。)有一些函数to_tsquery和plainto_tsquery有助于将用户编写的文本转换为正确的tsquery,例如通过规范化文本中出现的单词。 同样,to_tsvector用于解析和规范化文档字符串。 所以在实践中,文本搜索匹配看起来更像是这样的:

  1. SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');
  2. ?column?
  3. ----------
  4. t

如果写为,则发现此匹配不会成功

  1. SELECT 'fat cats ate fat rats'::tsvector @@ to_tsquery('fat & rat');
  2. ?column?
  3. ----------
  4. f

因为这里没有rats这个词的标准化。 tsvector的元素是词位,假设已经标准化,因此rats与rat不匹配。

@@运算符还支持文本输入,允许在简单情况下将文本字符串显式转换为tsvector或tsquery。 可用的变体是:

  1. tsvector @@ tsquery
  2. tsquery @@ tsvector
  3. text @@ tsquery
  4. text @@ text

我们已经看到了前两个。 形式text @@ tsquery等同于to_tsvector(x) @@ y。 形式text @@ text等同于to_tsvector(x) @@ plainto_tsquery(y)。

配置

以上都是简单的文本搜索示例。 如前所述,全文搜索功能包括执行更多操作的能力:跳过索引某些单词(停止词),处理同义词,以及使用复杂的解析,例如,基于不仅仅是空格的解析。 此功能由文本搜索配置控制。 Greenplum数据库附带了许多语言的预定义配置,您可以轻松创建自己的配置。 (psql的\dF命令显示所有可用的配置。)

在安装过程中,会选择适当的配置,并在postgresql.conf中相应地设置default_text_search_config。 如果您对整个集群使用相同的文本搜索配置,则可以使用postgresql.conf中的值。 要在整个集群中使用不同的配置,但在任何一个数据库中使用相同的配置,请使用 ALTER DATABASE … SET。 否则,您可以在每个会话中设置default_text_search_config。

每个依赖于配置的文本搜索功能都有一个可选的regconfig参数,因此可以显式指定要使用的配置。 default_text_search_config仅在省略此参数时使用。

为了更容易构建自定义文本搜索配置,可以从更简单的数据库对象构建配置。 Greenplum数据库的文本搜索工具提供了四种与配置相关的数据库对象:

  • 文本搜索解析器将文档分解为token并对每个token进行分类(例如,作为单词或数字)。
  • 文本搜索词典将token转换为标准化形式并拒绝停止词。
  • 文本搜索模板提供基本字典的功能。(字典只是为模板指定模板和一组参数。)
  • 文本搜索配置选择一个解析器和一组字典,用于规范化解析器生成的token。

文本搜索解析器和模板是从低级C函数构建的; 因此,它需要C编程才能开发新的,并且需要超级用户权限才能将其安装到数据库中。 (在Greenplum数据库发行版的contrib/区域中有附加解析器和模板的示例。) 由于字典和配置只是参数化并将一些底层解析器和模板连接在一起,因此创建新字典或配置不需要特殊权限。 本章稍后将介绍创建自定义词典和配置的示例。

对比Greenplum数据库文本搜索与Pivotal GPText

Greenplum数据库文本搜索是将PostgreSQL文本搜索移植到Greenplum数据库MPP平台。 Pivotal还提供Pivotal GPText,它将Greenplum数据库与Apache Solr文本搜索平台集成在一起。 GPText在您的Greenplum数据库集群旁边安装Apache Solr集群,并提供Greenplum数据库功能,您可以使用它来创建Solr索引,查询它们,并在数据库会话中接收结果。

这两个系统都提供强大的企业级文档索引和搜索服务。 Greenplum数据库文本搜索可立即供您使用,无需安装和维护其他软件。 如果它符合您的应用程序的要求,您应该使用它。

带有Solr的GPText具有Greenplum数据库文本搜索所不具备的许多功能。 特别是,GPText更适合高级文本分析应用程序。 以下是将GPText用于文本搜索应用程序时可以使用的一些优点和功能。

  • Apache Solr集群可以与数据库分开扩展。 Solr节点可以部署在Greenplum数据库主机上,也可以部署在网络上的不同主机上。
  • 可以将索引和搜索工作负载从Greenplum数据库移出到Solr,以维护数据库查询性能。
  • GPText创建分割为分片的Solr索引,每个Greenplum数据库segment一个,因此Greenplum数据库MPP体系结构的优势扩展到了文本搜索工作负载。
  • 使用Solr索引和搜索文档非常快,可以通过向集群添加更多Solr节点来扩展。
  • 文档内容可以存储在Greenplum数据库表,Solr索引或两者中。
  • 通过GPText,Solr可以索引存储为Greenplum数据库表格中文本的文档,以及使用HTTP,FTP,S3或HDFS URL访问的外部存储中的文档。
  • Solr自动识别大多数丰富的文档格式,并分别索引文档内容和元数据。
  • Solr索引可高度自定义。 您可以将文本分析链自定义到字段级别。
  • 除了Apache项目提供的大量语言,标记符和过滤器之外,GPText还提供社交媒体标记器,国际文本标记器和通用查询解析器,它们可以理解几种常见的文本搜索语法。
  • GPText API支持高级文本分析工具,例如分面,命名实体识别(NER)和词性(POS)识别。

有关GPText的详细信息,请参阅GPText文档网站

Parent topic: 使用全文搜索