• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

PostgreSQL全文检索

武飞扬头像
风间琉璃zero
帮助1

PostgreSQL全文检索

在日常的数据处理中,我们经常会有这样的需求:从一个文本中寻找某个字符串(比如某个单词)。

对这个需求,我们可以用类似这样的SQL完成:

SELECT * FROM student WHERE text LIKE ‘%pgsql%’;
(找到含有“pgsql”的文本)。

现在我们考虑一些特殊的情形:

  1. 需要查找的文本特别多,特别大;
  2. 不做单纯的字符串匹配,而是考虑自然语言的一些特性,比如匹配某一类字符串(域名、人名)或者匹配单词的所有形式
  3. 对中文的支持。

那么此时再用以上的 “SELECT … LIKE …” 就不明智了,因为对数据库来说,这样的SQL必然走的是全表扫描,那么当文本特别多、特别大的时候,查找效率就会很低。另外,这样的SQL也不会智能到可以处理自然语言的特性。

针对这一需要PostgreSQL提供了强大的全文搜索功能可以满足这样的需求。

PostgreSQL在8.3.x版本后开始支持全文检索。执行步骤,主要分三步走:

  1. 将文档分词 token,这些token可以是数字、单词、域名、人名、email的格式等等。在PG中可以定义一个parser(分析器)来做这个工作
  2. 转换分词规则如去掉复数后缀s/es,以及加入stop词,使之不会在分词 中出现
  3. 按一定顺序查询的优化方式存储 tsvector存储,使用tsquery查询

上述的这些操作都是对文本的预处理

tsvector

一个tsvector的值是唯一分词的分类列表,把一话一句词格式化为不同的词条,在进行分词处理的时候,tsvector会自动去掉分词中重复的词条,按照一定的顺序装入。例如:

SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector;
                   tsvector
----------------------------------------------------
 'a' 'on' 'and' 'ate' 'cat' 'fat' 'mat' 'rat' 'sat'

从上面的例子可以看出 ,通过tsvector把一个字符串按照空格进行分词,分词的顺序是按照长短和字母来排序的。

并且词条位置常量可以附属于每个词条,例如:

SELECT 'a:1 fat:2 cat:3 sat:4 on:5 a:6 mat:7 and:8 ate:9 a:10 fat:11 rat:12'::tsvector;
                     tsvector
-------------------------------------------------------------------------------
 'a':1,6,10 'on':5 'and':8 'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4

这个位置信息通常就是当前文档中单词所处的位置,这个位置信息用于关注度的体现。位置信息常量的值的范围为1 到 16383。分词后,会把相同词条的位置记录到一个词条中。(如上所示)。

词条通过权重可以使其所在位置促进它的标记。权重分为A,B,C,D,D为默认值可以不显示.

权重用于关系,体现文档结构是很有特色地.例如,通俗一点,就是相同的词条,但是词条所在位置的权重不一样,在一个文档中,标题和文本内容,在做全文检索排序功能时需要分配给这两个词不同的优先权,不同的权重标记.

理解tsvector类型是很重要的,不能只关注标准的应用.例如

select 'The Fat Rats'::tsvector;
      tsvector      
--------------------
 'Fat' 'The' 'Rats'

但是对于英文全文检索应用来说,上面的句子就是非标准化的,但是tsvector是不会知道的,为处理加工的文本应该通过使用to_tsvector函数来是之规格化,标注化的应用于搜索.

SELECT to_tsvector('english', 'The Fat Rats');         
   to_tsvector   
-----------------
 'fat':2 'rat':3

tsquery

tsquery是存储用于检索的词条.并且可以联合使用boolean 操作符来连接, & (AND), | (OR), & ! (NOT). 使用括号(),可以强制分为一组.

 SELECT 'fat & rat'::tsquery;
    tsquery    
---------------
 'fat' & 'rat'
SELECT 'fat & (rat | cat)'::tsquery;
    tsquery          
---------------------------
 'fat' & ( 'rat' | 'cat' )
SELECT 'fat & rat & ! cat'::tsquery;
    tsquery         
------------------------
 'fat' & 'rat' & !'cat'

同时,tsquery 在做搜索的时候,也可以使用权重,并且每个词都可以使用一个或者多个权重标记,这样在检索的时候,会匹配相同权重的信息.

跟上面的tsvector 相同tsquery也有一个to_tsquery函数.

在PG中,以上对文本的预处理可以通过一个函数to_tsvector来完成,函数的返回值是tsvector这个数据类型。
另外,对于待查找的单词,我们也要用to_tsquery这个函数包装起来,函数的返回值是tsquery这个数据类型。
一个简单的例子见下面,to_tsquery里的参数可以使用布尔运算符

SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');
 ?column?
----------
 t

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbghib
系列文章
更多 icon
同类精品
更多 icon
继续加载