PostgreSQL 全文搜索 文档解析函数
1 背景知识
全文搜索排序和去重是在输入文本期间自动完成的,因为要实现 全文搜索 必须从文档创建 tsvector 数据类型以及创建 tsquery 的查询。
PostgreSQL提供了函数 to_tsvector将一个文档转换成tsvector
数据类型。
2 to_tsvector 函数语法定义
to_tsvector([ config regconfig, ] document text) returns tsvector
参数 | 说明 |
---|---|
config regconfig | 指定正规化的语言规则。 |
document text | 指定要预处理的文档内容。 |
tsvector | 返回数据类型。 |
3 to_tsvector 函数文本处理过程
- 调用 解析器,将文档文本分解成
记号
,并且为每一种记号
分配一个类型。 - 对于每一个
记号
,函数会去查询一个 词典 列表。 将记号
正规化的词位
。例如,rats
变成rat
是因为一个词典识别到该词rats
是rat
的复数形式。 - 因为有些单词出现得太频繁,无法搜索索引。所以一些词会被识别为停用词,这将忽略它们,在我们的例子中有
a
、on
和it
是停用词。 - 如果没有词典能识别该记号,那它将也会被忽略。例如,标点符号
-
就属于这种情况,因为事实上没有词典会给它分配记号类型(空间符号
),即空间记号不会被索引。 - 对于解析器、词典以及要索引哪些记号类型是由所选择的 文本搜索配置 决定的。
- 可以在同一个数据库中有多种不同的配置,并且有用于很多种语言的预定义配置。在我们的例子中,我们使用适用英语的默认配置
english
。
4 to_tsvector 函数使用方式
SELECT to_tsvector('english', 'a fat cat sat on a mat - it ate a fat rats');
//屏幕输出:
to_tsvector
-----------------------------------------------------
'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4
(1 row)
Note
从上面返回结果可知:
tsvector
不包含词 a
、on
或 it
,词 rats
变成了 rat
,并且标点符号 -
被忽略了。
5 setweight 函数添加 词位
的权重
函数 setweight
用于对 tsvector
中的 词位
标注一个给定的 权重
,这里一个 权重
可以是四个字母之一:A
、B
、C
或 D
。权重用来标记来自文档不同部分的项,例如标题、正文。权重信息可以被用来排名搜索结果。
因为 to_tsvector
(NULL
) 将返回 NULL
,所以建议使用 coalesce
函数,避免空值造成的问题。
下面是从 film
表中创建一个 tsvector
的方法:
SELECT
setweight(to_tsvector(coalesce(title,'')), 'A') ||
setweight(to_tsvector(coalesce(special_features,'')), 'B') FROM film ;
//屏幕输出:
?column?
------------------------------
'behind':4B 'graffiti':2A 'scene':6B 'stranger':1A 'trailer':3B
'behind':7B 'commentari':4B 'delet':5B 'person':2A 'scene':6B,9B 'trailer':3B 'weekend':1A
'behind':5B 'cabin':2A 'commentari':4B 'scene':7B 'shock':1A 'trailer':3B
'behind':4B 'blind':1A 'gun':2A 'scene':6B 'trailer':3B
'behind':5B 'commentari':4B 'detail':2A 'motion':1A 'scene':7B 'trailer':3B
... ... ... ...
这里我们已经使用了 setweight
函数在 tsvector
标注每一个词位的来源,并将标注过的 tsvector
值用连接操作符 ||
合并在一起。如果想要了解更多操作符请见 操作符。