PostgreSQL · 特性介绍 · 全文搜索介绍
背景
在日常的数据处理中,我们经常会有这样的需求:从一个文本中寻找某个字符串(比如某个单词)。
对这个需求,我们可以用类似这样的SQL完成:SELECT * FROM tbl WHERE text LIKE '%rds PostgreSQL%';(找到含有“rds PostgreSQL”的文本)
现在我们考虑一些特殊的情形:
- 需要查找的文本特别多,特别大;
- 不做单纯的字符串匹配,而是考虑自然语言的一些特性,比如匹配某一类字符串(域名,人名)或者匹配单词的所有形式(不考虑它的词性及变化,比如have,has,had都匹配出来);
- 对中文自然语言特性的支持。
那么此时再用以上的“SELECT ... LIKE ...”就不明智了,因为对数据库来说,这样的SQL必然走的是全表扫描,那么当文本特别多,特别大的时候,查找效率就会很低。
另外,这样的SQL也不会智能到可以处理自然语言的特性。
怎么办呢?PostgreSQL(以下简称PG)提供了强大的全文搜索功能可以满足这样的需求。
对文本的预处理
全文搜索首先需要对文本预处理,包括3步:
- 将文本分解成一个个token,这些token可以是数字,单词,域名,人名,email的格式等等。在PG中可以定义一个parser来做这个工作。
- 将第一步分解成的token标准化,所谓的标准化就是利用一些规则将token分好类(比如人名是一类,域名是一类等等)。标准化后的token我们称之为lexeme。在PG中是通过定义一个词典来做这个工作。PG里最简单的词典simple的标准化过程就是将大写字母转成小写字母。
- 对文本打分,优化查找过程。比如对于待查找的词,文本1匹配的数量大于文本2匹配的数量,那么在这个查找过程,文本1的优先级大于文本2的优先级。
在PG中,以上对文本的预处理可以通过一个函数to_tsvector来完成,函数的返回值是tsvector这个数据类型。
另外,对于待查找的单词,我们也要用to_tsquery这个函数包装起来,函数的返回值是tsquery这个数据类型。
一个简单的例子见下面,to_tsquery里的参数可以使用运算符(&:与,|:或,!:非):
SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat');?column?
----------t
Quick Start
在了解了这些概念之后,我们用实际的例子来玩一玩PG的全文搜索。
我们在client端输入以下命令,dFp显示的是所有的parser,这里只有一个默认parser(default)。
dFp+ default 显示默认parser(default)的详细信息:parse的过程(5个函数),parse的Token类型(asciihword, asciiword...)。
sbtest=# \dFpList of text search parsersSchema | Name | Description
------------+---------+---------------------pg_catalog | default | default word parser
(1 row)sbtest=# \dFp+ defaultText search parser "pg_catalog.default"Method | Function | Description
-----------------+----------------+-------------Start parse | prsd_start | (internal)Get next token | prsd_nexttoken | (internal)End parse | prsd_end | (internal)Get headline | prsd_headline | (internal)Get token types | prsd_lextype | (internal)Token types for parser "pg_catalog.default"Token name | Description
-----------------+------------------------------------------asciihword | Hyphenated word, all ASCIIasciiword | Word, all ASCIIblank | Space symbolsemail | Email addressentity | XML entityfile | File or path namefloat | Decimal notationhost | Hosthword | Hyphenated word, all lettershword_asciipart | Hyphenated word part, all ASCIIhword_numpart | Hyphenated word part, letters and digitshword_part | Hyphenated word part, all lettersint | Signed integernumhword | Hyphenated word, letters and digitsnumword | Word, letters and digitsprotocol | Protocol headsfloat | Scientific notationtag | XML taguint | Unsigned integerurl | URLurl_path | URL pathversion | Version numberword | Word, all letters
(23 rows)
输入dF+ english,给出标准化各类英语token时所用到的dictionary:
sbtest=# \dF+ english
Text search configuration "pg_catalog.english"
Parser: "pg_catalog.default"Token | Dictionaries
-----------------+--------------asciihword | english_stemasciiword | english_stememail | simplefile | simplefloat | simplehost | simplehword | english_stemhword_asciipart | english_stemhword_numpart | simplehword_part | english_stemint | simplenumhword | simplenumword | simplesfloat | simpleuint | simpleurl | simpleurl_path | simpleversion | simpleword | english_stem
创建以default为parser的配置defcfg,并增加token映射,这里我们只关心email, url, host:
sbtest=# CREATE TEXT SEARCH CONFIGURATION defcfg (PARSER = default);
CREATE TEXT SEARCH CONFIGURATION
sbtest=# ALTER TEXT SEARCH CONFIGURATION defcfg ADD MAPPING FOR email,url,host WITH simple;
ALTER TEXT SEARCH CONFIGURATION
建好配置defcfg后,我们看看利用defcfg对文本进行处理的结果。这里使用to_tsvector函数,可以看到email,url,host都被识别出来了:
sbtest=# select to_tsvector('defcfg','xxx yyy xxx@taobao.com yyy@sina.com http://google.com/123 12345 ');to_tsvector
-----------------------------------------------------------------------'google.com':4 'google.com/123':3 'xxx@taobao.com':1 'yyy@sina.com':2
(1 row)
在实际对表内的文本做全文搜索时,一般对目标列建立gin索引(也就是倒排索引,详情见官方文档),这样可以加快查询效率,具体操作如下:
sbtest=# CREATE TABLE t1(c1 text);
CREATE TABLE
sbtest=# CREATE INDEX c1_idx ON t1 USING gin(to_tsvector('defcfg', c1));
CREATE INDEX
sbtest=# \d t1Table "public.t1"Column | Type | Modifiers
--------+------+-----------c1 | text |
Indexes:"c1_idx" gin (to_tsvector('defcfg'::regconfig, c1))
这里我们插入2条文本,并做一些匹配:
sbtest=# INSERT INTO t1 VALUES('xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345');
INSERT 0 1
sbtest=# INSERT INTO t1 VALUES('xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345');
INSERT 0 1
sbtest=# select * from t1;c1
-------------------------------------------------------------xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345
(2 rows)sbtest=# select * from t1 where to_tsvector('defcfg',c1) @@ 'google.com';c1
-------------------------------------------------------------xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345
(2 rows)sbtest=# select * from t1 where to_tsvector('defcfg',c1) @@ to_tsquery('google.com & yyy@sina.com');c1
-------------------------------------------------------------xxx yyy xxx@taobao.com yyy@sina.com http://google.com 12345xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345
(2 rows)sbtest=# select * from t1 where to_tsvector('defcfg',c1) @@ to_tsquery('google.com & xxx@gmail.com');c1
------------------------------------------------------------xxx yyy xxx@gmail.com yyy@sina.com http://google.com 12345
(1 row)
以上的操作都是针对英文,实际上对中文也是支持的,不过会稍微麻烦点,因为中文的token必须通过分词才能产生,所以需要先装分词的组件scws和zhparser,具体可以参考这篇博文。
结语
本文对PG的全文搜索做了一个入门级的介绍,方便用户快速上手,如果需要对全文搜索作更深入的研究,建议阅读官方文档第12章。
PostgreSQL · 特性介绍 · 全文搜索介绍相关推荐
- PostgreSQL SQL 语言:全文搜索
本文档为PostgreSQL 9.6.0文档,本转载已得到原译者彭煜玮授权. 1. 介绍 全文搜索(或者文本搜索)提供了确定满足一个查询的自然语言文档的能力,并可以选择将它们按照与查询的相关度排序.最 ...
- Cloud Studio全文搜索功能介绍
使用全文搜索功能可以在整个项目文件中进行关键字搜索.点击左侧的搜索按钮,或者使用快捷键 cmd+shift+f(Windows 下是 cmd+shift+f),就可以打开全文搜索面板. 输入关键词回车 ...
- mysql against 中文_「against的用法」Mysql全文搜索之MATCH...AGAINST的用法介绍 - seo实验室...
against的用法 前提:mysql只支持英文内容的全文索引,所以只考虑英文的全文搜索.假定数据表名为post,有三列:id.title.content.id是自增长序号,title是varchar ...
- Mysql全文搜索之MATCH...AGAINST的用法介绍
前提:mysql只支持英文内容的全文索引,所以只考虑英文的全文搜索.假定数据表名为post,有三列:id.title.content.id是自增长序号,title是varchar,content是te ...
- ES(ElasticSearch)分布式全文搜索引擎介绍及使用方式
1.什么是ES **ES** 全称 **ElasticSearch** 是一种分布式全文搜索引擎,基于Lucene(全文搜索框架)开发而来. Lucene是公认的迄今为止的最好用的搜索引擎库,但是他所 ...
- 搜索介绍 | 当你搜索时,发生了什么?
全文目录如下: 一如"万物皆可百度"."万物无难事,只要肯百度"所言,搜索在我们生活中早已成为习以为常的事情.毕业季的我们会在每日99+的群聊信息中搜索所需的信 ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 12 章 全文搜索_12.9. GIN 和 GiST 索引类型
12.9. GIN 和 GiST 索引类型 有两种索引可以被用来加速全文搜索.注意全文搜索并非一定需要索引,但是在一个定期会被搜索的列上,通常需要有一个索引. CREATE INDEX name ON ...
- linux下软件发布,Linux Kernel 5.12发布下载,附新特性及新功能介绍
Linus Torvalds在Linux内核邮件列表中宣布正式发布Linux Kernel 5.12版本,已提供linux-5.12.tar.xz/tar.gz下载,以下为你介绍该版本的更改.新特性及 ...
- 指尖江湖李忘生鸿蒙初开,剑网3指尖江湖李忘生怎么样_李忘生装备搭配、技能特性、解锁方法介绍_游戏吧...
李忘生现任纯阳掌教,纯阳五子之首,道号"玉虚子".下面游戏吧小编将为大家带来了李忘生装备属性.技能特性.解锁方法介绍,快来了解一下吧! 解锁方法 获取方法:通过提升和他的好感度获取 ...
最新文章
- scrum看板工具做问题跟踪
- leetcode @38报数-js
- 一堂如何提高代码质量的培训课【转】
- 如何让.net程序自动运行在管理员权限下
- WinSCP+PuTTY搭配使用 ,解决Windows连接Linux系统文件传输和终端登陆
- python计算每月工资多少钱_[Python]CCF——工资计算(201612-2)
- 微博技术专家陈波:百亿级访问量的应用如何做缓存架构设计
- 特斯拉股价周一大跌8.55% 市值缩水640亿美元
- 第二场周赛(递归递推个人Rank赛)——题解
- 逍遥android模拟器设置,逍遥安卓模拟器最佳设置电脑上玩手游流畅不卡多开更好用...
- Hadoop3——集群搭建以及初体验
- timeSetEvent的用法(一)
- 机器学习、神经网络、深度学习的关系
- 计算机课的十个小游戏制作教程,腾讯内容开放平台
- [02/Dec/2019:12:59:10 +0800]之日期转换
- 中国开发者将迎来黄金十年
- 女大学生王婷婷致信给网上春光照女主角
- 关于千牛移动端纯H5插件和QAP应用中H5页面的概念
- Ubuntu下解压rar文件的方法
- Shellshock 破壳漏洞(CVE-2014-6271)
热门文章
- linux命令重定向、、 1、 2、 1、 2、
- vector 对某个下标排序_Python实现堆排序
- python词云cannot open resource_centos flask验证码pil提示OSError: cannot open resource,问题解决方法...
- python如何使用sdk_七牛云存储Python SDK使用教程 - 基本介绍
- oracle中rac是什么意思,Oracle中HA、RAC、Datagurad区别
- 人力资源管理4个过程及相关重点
- Linux定制登录欢迎语
- Openlayers中使用Cluster+Overlay实现点击单个要素和聚合要素时显示不同弹窗
- 信息系统项目管理师-合同法、招投标法、政府采购法、著作权法考点笔记
- MyBatis中提示:Invalid Bound statemnet(not found )com.