8.11. 文本搜索类型

**PostgreSQL**提供两种数据类型,它们被设计用来支持全文搜索,全文搜索是一种在自然语言的文档 集合中搜索以定位那些最匹配一个查询 的文档的活动。tsvector类型表示一个为文本搜索优化的形式下的文档,tsquery类型表示一个文本查询。第 12 章提供了对于这种功能的详细解释,并且第 9.13 节总结了相关的函数和操作符。

8.11.1. tsvector

  • 一个tsvector值是一个排序的可区分词位 的列表,词位 是被正规化 合并了同一个词的不同变种的词(详见第 12 章)。排序和去重是在输入期间自动完成的,如下例所示:
    SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector;
                          tsvector
    ---------------------------------------------------- 
     'a' 'and' 'ate' 'cat' 'fat' 'mat' 'on' 'rat' 'sat'
    
  • 要表示包含空白或标点的词位,将它们用引号包围:
    SELECT $$the lexeme '    ' contains spaces$$::tsvector;
                     tsvector
    ------------------------------------------- 
     '    ' 'contains' 'lexeme' 'spaces' 'the'
    
  • (我们在这个例子中使用美元符号包围的串文字并且下一个用来避免在文字中包含双引号记号产生的混淆)。嵌入的引号和反斜线必须被双写:
    SELECT $$the lexeme 'Joe''s' contains a quote$$::tsvector;
                        tsvector
    ------------------------------------------------ 
     'Joe''s' 'a' 'contains' 'lexeme' 'quote' 'the'
    
  • 可选的,整数位置 可以被附加给词位:
    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 'and':8 'ate':9 'cat':3 'fat':2,11 'mat':7 'on':5 'rat':12 'sat':4
    

一个位置通常表示源词在文档中的定位。位置信息可以被用于邻近排名 。位置值可以从 1 到 16383,更大的数字会被 16383。对于相同的词位出现的重复位置将被丢弃。

  • 具有位置的词位可以进一步地被标注一个权重 ,它可以是A、 B、C或D。 D是默认值并且因此在输出中不会显示:
    SELECT 'a:1A fat:2B,4C cat:5D'::tsvector;
              tsvector
    ---------------------------- 
     'a':1A 'cat':5 'fat':2B,4C
    

权重通常被用来反映文档结构,例如将主题词标记成与正文词不同。文本搜索排名函数可以为不同的权重标记器分配不同的优先级。

  • 了解tsvector类型本身并不执行任何正规化这一点很重要,它假定给它的词已经被恰当地为应用正规化过。例如:
    select 'The Fat Rats'::tsvector;
          tsvector
    -------------------- 
     'Fat' 'Rats' 'The'
    
  • 对于大部分英语文本搜索应用,上面的词将会被认为是非正规化的,但是tsvector并不在乎这一点。原始文档文本通常应该经过to_tsvector以恰当地为搜索正规化其中的词:
    SELECT to_tsvector('english', 'The Fat Rats');
       to_tsvector
    ----------------- 
     'fat':2 'rat':3
    
  • 再次地,详情请参阅第 12 章。

8.11.2. tsquery

  • 一个tsquery值存储要用于搜索的词位,并且使用布尔操作符&(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'
    

如果没有圆括号,则!(NOT)优先级最高,&(AND)次之,|(OR)最低。

  • 可选地,一个tsquery中的词位可以被标注一个或多个权重字母,这将限制它们只能和具有匹配权重的tsvector词位相匹配:
    SELECT 'fat:ab & cat'::tsquery;
        tsquery
    ------------------ 
     'fat':AB & 'cat'
    
  • 此外,一个tsquery中的词位可以被标注为*来指定前缀匹配:
    SELECT 'super:*'::tsquery;
      tsquery
    ----------- 
     'super':*
    
  • 这个查询将匹配一个tsvector中以"super"开头的任意词。注意前缀首先会被文本搜索配置所处理,它意味着这个比较返回真值:
    SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' );
     ?column?
    ---------- 
     t
    (1 row)
    
  • 因为postgres起源于postgr:
    SELECT to_tsquery('postgres:*');
     to_tsquery
    ------------ 
     'postgr':*
    (1 row)
    
  • 则匹配postgraduate。
  • 词位的引号规则和之前描述的tsvector中的词位相同;并且,正如tsvector,任何请求的词正规化必须在转换到tsquery类型之前完成。to_tsquery函数可以方便地执行这种正规化:
    SELECT to_tsquery('Fat:ab & Cats');
        to_tsquery
    ------------------ 
     'fat':AB & 'cat'
    
下一节:数据类型uuid存储由RFC 4122、ISO/IEC 9834-8:2005以及相关标准定义的通用唯一标识符(UUID)(某些系统将这种数据类型引用为全局唯一标识符GUID)。这种标识符是一个128位的量,它由一个精心选择的算法产生,该算法能保证在已知空间中任何其他使用相同算法的人能够产生同一个标识符的可能性非常非常小。因此,对于分布式系统,这些标识符相比序列生成器而言提供了一种很好的唯一性保障,序列生成器只能在一个数据库中保证唯一。