PostgreSQL 10.1 手册_部分 II. SQL 语言_第 12 章 全文搜索_12.4. 额外特性
12.4. 额外特性
- 12.4.1. 操纵文档12.4.2. 操纵查询12.4.3. 用于自动更新的触发器12.4.4. 收集文档统计数据
这一节描述在文本搜索中有用的一些额外的函数和操作符。
12.4.1. 操纵文档
第 12.3.1 节展示了未经处理的文本文档如何被转换成tsvector
值。PostgreSQL也提供了用于操纵已经为tsvector
形式的文档的函数和操作符。
-
tsvector
||tsvector
-
tsvector
连接操作符返回一个向量,它结合了作为参数给出的两个向量的词位和位置信息。位置和权重标签在连接期间被保留。出现在右手向量中的位置被使用左手向量中提到的最大位置进行偏移,这样结果几乎等于在两个原始文档字符串的连接上执行to_tsvector
的结果(这种等价不是完全的,因为从左手参数的尾端移除的任何停用词将会影响结果,而如果文本连接被使用它们就影响了右手参数中的词位位置)。使用向量形式的连接而不是在应用
to_tsvector
之前连接文本的一个优点是你可以使用不同配置来解析文档的不同小节。此外,因为setweight
函数按照相同的方式标记给定向量的所有词位,如果你想把文档的不同部分标注不同的权重,你就有必要解析文本并且在连接之前做setweight
。 -
setweight(
vector
tsvector
,weight
"char"
) returnstsvector
-
setweight
返回输入向量的一个拷贝,其中每一个位置都被标注为给定的权重
:A
、B
、C
或D
(D
是新向量的默认值并且并不会被显示在输出上)。向量被连接时会保留这些标签,允许来自文档的不同部分的词被排名函数给予不同的权重。注意权重标签是应用到位置而不是词位。如果输入向量已经被剥离了位置,则
setweight
什么也不会做。 -
length(
vector
tsvector
) returnsinteger
-
返回存储在向量中的词位数。
-
strip(
vector
tsvector
) returnstsvector
-
返回一个向量,其中列出了和给定向量相同的词位,不过没有任何位置或者权重信息。其结果通常比未被剥离的向量小很多,但是用处也小很多。和未被剥离的向量一样,相关度排名在已剥离的向量上也不起作用。此外,
<->
(FOLLOWED BY)tsquery
操作符不会匹配已剥离的输入,因为它无法确定词位之间的距离。
表 9.41中有tsvector
相关函数的完整列表。
12.4.2. 操纵查询
第 12.3.2 节展示了未经处理的文本形式的查询如何被转换成tsquery
值。PostgreSQL也提供了用于操纵已经是tsquery
形式的查询的函数和操作符。
-
tsquery
&&tsquery
-
返回用 AND 结合的两个给定查询。
-
tsquery
||tsquery
-
返回用 OR 结合的两个给定查询。
-
!!
tsquery -
返回一个给定查询的反(NOT)。
-
tsquery
<->tsquery
-
返回一个查询,它用
<->
(FOLLOWED BY)tsquery
操作符搜索两个紧跟的匹配,第一个匹配符合第一个给定的查询而第二个匹配符合第二个给定的查询。例如:SELECT to_tsquery('fat') <-> to_tsquery('cat | rat');?column? -----------------------------------'fat' <-> 'cat' | 'fat' <-> 'rat'
-
tsquery_phrase(
query1
tsquery
,query2
tsquery
[,distance
integer
]) returnstsquery
-
返回一个查询,它使用
<
N
>tsquery
操作符搜索两个距离为distance
个词位的匹配,第一个匹配符合第一个给定的查询而第二个匹配符合第二个给定的查询。例如:SELECT tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10);tsquery_phrase ------------------'fat' <10> 'cat'
-
numnode(
query
tsquery
) returnsinteger
-
返回一个
tsquery
中的结点数(词位外加操作符)。要确定查询
是否有意义或者是否只包含停用词时,这个函数有用,在前一种情况它返回 > 0,后一种情况返回 0。例子:SELECT numnode(plainto_tsquery('the any')); NOTICE: query contains only stopword(s) or doesn't contain lexeme(s), ignorednumnode ---------0SELECT numnode('foo & bar'::tsquery);numnode ---------3
-
querytree(
query
tsquery
) returnstext
-
返回一个
tsquery
中可以被用来搜索一个索引的部分。这个函数可用来检测不可被索引的查询,例如那些只包含停用词或者只有否定术语的查询。例如:SELECT querytree(to_tsquery('!defined'));querytree -----------
12.4.2.1. 查询重写
ts_rewrite
函数族在一个给定的tsquery
中搜索一个目标子查询的出现,并且将每一次出现替换成一个替补子查询。本质上这个操作就是一个tsquery
版本的子串替换。一个目标和替补的组合可以被看成是一个查询重写规则。一个这类重写规则的集合可以是一个强大的搜索助手。例如,你可以使用同义词扩展搜索(如,new york
、big apple
、nyc
、gotham
),或者收缩搜索来将用户导向某些特点主题。在这个特性和分类词典(第 12.6.4 节)有些功能重叠。但是,你可以随时修改一组重写规则而无需重索引,而更新一个分类词典则要求进行重索引才能生效。
-
ts_rewrite (
query
tsquery
,target
tsquery
,substitute
tsquery
) returnstsquery
-
这种形式的
ts_rewrite
简单地应用一个单一重写规则:不管target
出现在query
中的那个地方,它都被substitute
替代。例如:SELECT ts_rewrite('a & b'::tsquery, 'a'::tsquery, 'c'::tsquery);ts_rewrite ------------'b' & 'c'
-
ts_rewrite (
query
tsquery
,select
text
) returnstsquery
-
这种形式的
ts_rewrite
接受一个开始query
和一个 SQLselect
命令,它们以一个文本字符串的形式给出。select
必须得到tsquery
类型的两列。对于select
结果的每一行,在当前query
值中出现的第一列值(目标)被第二列值(替补)所替换。例如:CREATE TABLE aliases (t tsquery PRIMARY KEY, s tsquery); INSERT INTO aliases VALUES('a', 'c');SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases');ts_rewrite ------------'b' & 'c'
注意当多个重写规则被以这种方式应用时,应用的顺序很重要;因此在实际中你会要求源查询按某些排序键
ORDER BY
。
让我们考虑一个现实的天文学例子。我们将使用表驱动的重写规则扩展查询supernovae
:
CREATE TABLE aliases (t tsquery primary key, s tsquery); INSERT INTO aliases VALUES(to_tsquery('supernovae'), to_tsquery('supernovae|sn'));SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT * FROM aliases');ts_rewrite ---------------------------------'crab' & ( 'supernova' | 'sn' )
我们可以通过只更新表来改变重写规则:
UPDATE aliases SET s = to_tsquery('supernovae|sn & !nebulae') WHERE t = to_tsquery('supernovae');SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT * FROM aliases');ts_rewrite ---------------------------------------------'crab' & ( 'supernova' | 'sn' & !'nebula' )
当有很多重写规则时,重写可能会很慢,因为它要为为每一个可能的匹配检查每一条规则。要过滤掉明显不符合的规则,我们可以为tsquery
类型使用包含操作符。在下面的例子中,我们只选择那些可能匹配原始查询的规则:
SELECT ts_rewrite('a & b'::tsquery,'SELECT t,s FROM aliases WHERE ''a & b''::tsquery @> t');ts_rewrite ------------'b' & 'c'
12.4.3. 用于自动更新的触发器
当使用一个单独的列来存储你的文档的tsvector
表示时,有必要创建一个触发器在文档内容列改变时更新tsvector
列。两个内建触发器函数可以用于这个目的,或者你可以编写你自己的触发器函数。
tsvector_update_trigger(tsvector_column_name, config_name, text_column_name [, ... ]) tsvector_update_trigger_column(tsvector_column_name, config_column_name, text_column_name [, ... ])
这些触发器函数在CREATE TRIGGER
命令中指定的参数控制下,自动从一个或多个文本列计算一个tsvector
列。它们使用的一个例子是:
CREATE TABLE messages (title text,body text,tsv tsvector );CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON messages FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(tsv, 'pg_catalog.english', title, body);INSERT INTO messages VALUES('title here', 'the body text is here');SELECT * FROM messages;title | body | tsv ------------+-----------------------+----------------------------title here | the body text is here | 'bodi':4 'text':5 'titl':1SELECT title, body FROM messages WHERE tsv @@ to_tsquery('title & body');title | body ------------+-----------------------title here | the body text is here
在创建了这个触发器后,在title
或body
中的任何修改将自动地被反映到tsv
中,不需要应用来操心同步的问题。
第一个触发器参数必须是要被更新的tsvector
列的名字。第二个参数指定要被用来执行转换的文本搜索配置。对于tsvector_update_trigger
,配置名被简单地用第二个触发器参数给出。如上所示,它必须是模式限定的,因此该触发器行为不会因为search_path
中的改变而改变。对于tsvector_update_trigger_column
,第二个触发器参数是另一个表列的名称,它必须是类型regconfig
。这允许做一种逐行的配置选择。剩下的参数是文本列的名称(类型为text
、varchar
或char
)。它们将按给定的顺序被包括在文档中。NULL 值将被跳过(但是其他列仍将被索引)。
这些内建触发器的一个限制是它们将所有输入列同样对待。要对列进行不同的处理 — 例如,使标题的权重和正文的不同 — 就需要编写一个自定义触发器。下面是用PL/pgSQL作为触发器语言的一个例子:
CREATE FUNCTION messages_trigger() RETURNS trigger AS $$ beginnew.tsv :=setweight(to_tsvector('pg_catalog.english', coalesce(new.title,'')), 'A') ||setweight(to_tsvector('pg_catalog.english', coalesce(new.body,'')), 'D');return new; end $$ LANGUAGE plpgsql;CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATEON messages FOR EACH ROW EXECUTE PROCEDURE messages_trigger();
记住当在触发器内创建tsvector
值时,显式地指定配置名非常重要,这样列的内容才不会被default_text_search_config
的改变所影响。如果不这样做很可能导致问题,例如在转储并重新载入之后搜索结果改变。
12.4.4. 收集文档统计数据
ts_stat
被用于检查你的配置以及寻找候选的停用词。
ts_stat(sqlquerytext
, [weights
text
, ]OUT wordtext
, OUT ndocinteger
,OUT nentryinteger
) returnssetof record
sqlquery
是一个文本值,它包含一个必须返回单一tsvector
列的 SQL 查询。ts_stat
执行该查询并返回有关包含在该tsvector
数据中的每一个可区分词位(词)的统计数据。返回的列是:
word
text
— 一个词位的值ndoc
integer
— 词出现过的文档(tsvector
)的数量nentry
integer
— 词出现的总次数
如果提供了权重
,只有具有其中之一权重的出现才被计算在内。
例如,要在一个文档集合中查找十个最频繁的词:
SELECT * FROM ts_stat('SELECT vector FROM apod') ORDER BY nentry DESC, ndoc DESC, word LIMIT 10;
同样的要求,但是只计算以权重A
或B
出现的次数:
SELECT * FROM ts_stat('SELECT vector FROM apod', 'ab') ORDER BY nentry DESC, ndoc DESC, word LIMIT 10;
本文转自PostgreSQL中文社区,原文链接:12.4. 额外特性
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 12 章 全文搜索_12.4. 额外特性相关推荐
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.23. 行和数组比较
9.23. 行和数组比较 9.23.1. IN9.23.2. NOT IN9.23.3. ANY/SOME (array)9.23.4. ALL (array)9.23.5. 行构造器比较9.23.6 ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 12 章 全文搜索_12.9. GIN 和 GiST 索引类型
12.9. GIN 和 GiST 索引类型 有两种索引可以被用来加速全文搜索.注意全文搜索并非一定需要索引,但是在一个定期会被搜索的列上,通常需要有一个索引. CREATE INDEX name ON ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.4. 字符串函数和操作符...
9.4. 字符串函数和操作符 9.4.1. format 本节描述了用于检查和操作字符串值的函数和操作符.在这个环境中的串包括所有类型character.character varying和text的 ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 8 章 数据类型_8.10. 位串类型
8.10. 位串类型 位串就是一串 1 和 0 的串.它们可以用于存储和可视化位掩码.我们有两种类型的 SQL 位类型:bit(n)和bit varying(n),其中 n是一个正整数. bit类型的 ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 5 章 数据定义_5.11. 外部数据
5.11. 外部数据 PostgreSQL实现了部分的SQL/MED规定,允许我们使用普通SQL查询来访问位于PostgreSQL之外的数据.这种数据被称为外部数据(注意这种用法不要和外键混淆,后者是 ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.15. JSON 函数和操作符...
9.15. JSON 函数和操作符 表 9.43展示了可以用于两种 JSON 数据类型(见第 8.14 节)的操作符. 表 9.43. json和jsonb 操作符 操作符 右操作数类型 描述 例子 ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 10 章 类型转换_10.4. 值存储
10.4. 值存储 将被插入到一个表的值会按照下列步骤被转换到目标列的数据类型. 值存储类型转换 检查一个与目标的准确匹配. 否则,尝试转换表达式为目标类型.如果在两种类型之间的一个 赋值造型已经被注 ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 8 章 数据类型_8.6. 布尔类型
8.6. 布尔类型 PostgreSQL提供标准的SQL类型boolean,参见表 8.19.boolean可以有多个状态:"true(真)"."false(假)&quo ...
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 5 章 数据定义_5.5. 修改表
5.5. 修改表 5.5.1. 增加列5.5.2. 移除列5.5.3. 增加约束5.5.4. 移除约束5.5.5. 更改列的默认值5.5.6. 修改列的数据类型5.5.7. 重命名列5.5.8. 重命 ...
最新文章
- 30个流行的jQuery Plugins
- linux who命令实现,linux下 who命令(3)(示例代码)
- ASP.NET之纠错
- 趣学python3(48)--列出所有目录及子目录文件
- JavaScript上传图片及时预览
- golang-gui编程
- azure api 管理_Azure Cosmos DB和MongoDB API入门
- 中国专业开发者最多,最受 Web 服务青睐,Java 8 为最受欢迎版本 | 2020 年 Java 开发现状大调查...
- npm修改全局包安装路径
- Python源码深度解析—对象的创建
- Java类加载机制与反射 jvm学习
- java lcs矩阵,LCS算法的两种JAVA实现方式
- 电脑参数,台式电脑怎么查看配置参数|如何查询台式机硬件配置
- OPENCV函数介绍:normalize()
- JZOJ100047. 【NOIP2017提高A组模拟7.14】基因变异
- java实现京东云第三方登录
- alt tab无法切换窗口
- 计算机错误651是什么故障,宽带连接错误显示代码651是什么原因 宽带连接错误651的解决方法...
- MapReduce基本概述——分布式计算框架
- c程序设计语言k rpdf,《C程序设计语言》(KR)中文高清非扫描件