PostgreSQL全文检索

news/2024/7/9 21:42:29 标签: postgresql, 数据库, sql, 数据库开发

  • PostgreSQL全文检索
    • tsvector
    • tsquery

PostgreSQL全文检索

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

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

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会自动去掉分词中重复的词条,按照一定的顺序装入。例如:

sql">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把一个字符串按照空格进行分词,分词的顺序是按照长短和字母来排序的。

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

sql">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类型是很重要的,不能只关注标准的应用.例如

sql">select 'The Fat Rats'::tsvector;
      tsvector      
--------------------
 'Fat' 'The' 'Rats'

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

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

tsquery

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

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

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

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

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

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

http://www.niftyadmin.cn/n/1786487.html

相关文章

css grid随页面大小_不可忽视的CSS布局

前言CSS布局是一个前端必备的技能,HTML如果说是结构之美,CSS就是视觉之美可以给用户不一样的体验的效果和视觉冲击。如果一个大方美观的布局,用户第一眼看到会很舒服,不仅提高了用户的视觉效果也提高了用户的体验效果。随着现在设备种类的增多,各种大小不一,奇形怪状的设备使得…

软件测试容易忽略的问题分析

软件测试容易忽略的问题分析1. 配置文件缺陷2. 输入顺序缺陷3. 输入框内容缺陷4. 界面布局缺陷5. 升级缺陷6. 调试语句和冗余信息7. 网页安全缺陷8. 卸载缺陷1. 配置文件缺陷 大多数软件在安装完成后都或多或少会有相应的配置文件,这些配置文件在一般的测试中大多是…

c语言 头文件可以定义的函数吗_很多程序员都不知道,C语言函数不能返回数组,却可以返回结构体...

来自:今日头条,作者:IT刘小虎链接:https://www.toutiao.com/a6748359298394358285/最近有读者问我,为什么C语言函数可以返回结构体,却不可以返回数组。有这样的问题并不奇怪,因为C语言数组和结构…

常见加密方式以及使用场景

一、加密和解密什么是加密什么是解密二、对称加密和非对称加密对称加密工作原理优缺点非对称加密工作原理优缺点三、摘要加密算法特点一、加密和解密 什么是加密 数据加密的基本过程,就是对原来为明文 的文件或数据按 某种算法 进行处理,使其成为 不可…

语言逻辑运算符两侧运算对象_C语言运算符知识

目录: 【算术运算符】【自增运算符】【自减运算符】【关系运算符】【逻辑运算符】【三目运算符】【sizeof运算符】 作用1.算术运算符(加)、-(减)、*(乘)、/(除)、%(取余、模)注: 取余结果与%左边有关。 数据类型决定数据精度。2.自增运算符a 先加后用 //…

PostgreSQL锁机制浅析

表级锁的类型 1.ACCESS SHARE(访问共享锁)2.ROW SHARE(行共享锁)3.ROW EXCLUSIVE(行排他锁)4.SHARE UPDATE EXCLUSIVE(共享更新排他锁&#xff09…

appium文件夹下无.bin文件_如何批量获取同一文件夹下所有的文件名

关注表哥公众号的读者朋友们大家都了解我是最爱“偷懒”的,我说的偷懒当然指的是:『合理偷懒』今天给大家介绍一种批量获取同一文件夹下所有的文件名称的巧妙办法,能够帮忙我们合理偷懒,这也是我在工作实践中无意发现的。相信很多…