8.11. Tipos de dados de procura de texto completo #

8.11.1. tsvector
8.11.2. tsquery
8.11.3. tsvector versus tsquery

O PostgreSQL fornece dois tipos de dados projetados para dar suporte à procura de texto completo, a qual é a atividade de procurar numa coleção de documentos escritos em linguagem natural os documentos que melhor correspondem à consulta efetuada. O tipo de dados tsvector representa o documento em uma forma otimizada para procura de texto completo, enquanto o tipo tsquery representa de forma semelhante uma consulta. O Capítulo 12 fornece uma explicação detalhada desta capacidade, e a Seção 9.13 resume as funções e operadores relacionados.

8.11.1. tsvector #

Um valor do tipo de dados tsvector é uma lista ordenada de lexemas [49] [50] distintos, as quais são palavras normalizadas para fundir diferentes formas alternativas da mesma palavra (veja o Capítulo 12 para obter detalhes). A classificação e a eliminação de valores duplicados são feitas automaticamente durante a entrada, como mostrado no seguinte exemplo:

SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector;

                      tsvector
----------------------------------------------------
 'a' 'and' 'ate' 'cat' 'fat' 'mat' 'on' 'rat' 'sat'

Para representar lexemas contendo espaços em branco ou pontuação, os lexemas devem ser colocados entre apóstrofos:

SELECT $$o lexema '    ' contém espaços$$::tsvector;

                tsvector
----------------------------------------
 '    ' 'contém' 'espaços' 'lexema' 'o'

(Foram usados literais cadeias de caracteres delimitados por cifrão ($$), nesse exemplo e no próximo, para evitar a confusão do uso de apóstrofos dobrados dentro de literais.). Apóstrofos e contrabarras incorporados devem ser dobrados:

SELECT $$o lexema D'Almeida 'D''Almeida' contém apóstrofo$$::tsvector;

                    tsvector
------------------------------------------------
 'D''Almeida' 'apóstrofo' 'contém' 'lexema' 'o'

Opcionalmente, posições inteiras podem ser anexadas aos lexemas:

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

Uma posição normalmente indica a localização da palavra de origem no documento. As informações sobre a posição podem ser usadas para obter uma pontuação de proximidade. Os valores de posição podem variar de 1 a 16383; números maiores são silenciosamente limitados a 16383. As posições duplicadas do mesmo lexema são descartadas.

Os lexemas que possuem posições podem ainda ser rotulados com um peso, que pode ser A, B, C ou D. D é o padrão, portanto não é mostrado na saída:

SELECT 'a:1A fat:2B,4C cat:5D'::tsvector;

          tsvector
----------------------------
 'a':1A 'cat':5 'fat':2B,4C

Normalmente os pesos são usados para refletir a estrutura do documento, por exemplo, marcando as palavras do título de forma diferente das palavras do corpo do documento. As funções de classificação de procura de texto podem atribuir diferentes prioridades aos diferentes marcadores de peso.

É importante entender que o tipo de dados tsvector não realiza nenhuma normalização de palavras por si próprio; ele assume que as palavras fornecidas estão normalizadas de forma apropriada para a aplicação. Por exemplo,

SELECT 'The Fat Rats'::tsvector;

      tsvector
--------------------
 'Fat' 'Rats' 'The'

Para a maioria das aplicações de procura de texto em inglês, as palavras acima seriam consideradas não normalizadas, mas o tipo de dados tsvector não se importa com isso. O texto bruto do documento deve geralmente ser passado pela função to_tsvector para normalizar as palavras de forma apropriada para procura:

SELECT to_tsvector('english', 'The Fat Rats'); -- Em inglês

   to_tsvector
-----------------
 'fat':2 'rat':3

SELECT to_tsvector('portuguese','Os Ratos Gordos'); -- Em português (N. T.)

   to_tsvector
------------------
 'gord':3 'rat':2

Novamente, veja o Capítulo 12 para obter mais detalhes.

8.11.2. tsquery #

O valor do tipo de dados tsquery armazena os lexemas que devem ser procurados, e pode combiná-los usando os operadores booleanos & (AND), | (OR) e ! (NOT), assim como o operador de procura de frase <-> (FOLLOWED BY). Também existe a forma alternativa <N> do operador FOLLOWED BY, onde N é uma constante inteira que especifica a distância entre os dois lexemas sendo procurados. <-> equivale a <1>.

Podem ser usados parênteses para forçar o agrupamento desses operadores. Na ausência de parênteses, ! (NOT) é o que liga mais firmemente, <-> (FOLLOWED BY) é o próximo que liga mais firmemente e, por último, & (AND) junto com | (OR) são os que ligam menos firmemente.

A seguir estão alguns exemplos:

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'

Opcionalmente, os lexemas no tipo de dados tsquery podem ser rotulados com uma ou mais letras de peso, o que os restringe a corresponder apenas aos lexemas tsvector com um desses pesos:

SELECT 'fat:ab & cat'::tsquery;

    tsquery
------------------
 'fat':AB & 'cat'

Além disso, os lexemas no tipo de dados tsquery podem ser rotulados com * para especificar a correspondência de prefixo:

SELECT 'super:*'::tsquery;

  tsquery
-----------
 'super':*

Esta consulta corresponde a qualquer palavra no tipo de dados tsvector que comece por super.

As regras de delimitação para os lexemas são as mesmas descritas anteriormente para os lexemas no tipo de dados tsvector; e, como no tipo de dados tsvector, qualquer normalização de palavras necessária deve ser feita antes de converter para o tipo de dados tsquery. A função to_tsquery é conveniente para realizar tal normalização:

SELECT to_tsquery('Fat:ab & Cats');

    to_tsquery
------------------
 'fat':AB & 'cat'

Note que a função to_tsquery processa prefixos da mesma forma que as outras palavras, significando que essa comparação retorna verdade:

SELECT to_tsvector('english', 'postgraduate' )
    @@ to_tsquery('english', 'postgres:*' );

 ?column?
----------
 t

porque postgres fica cortado para postgr

SELECT to_tsvector('english', 'postgraduate' ),
       to_tsquery('english', 'postgres:*' );

  to_tsvector  | to_tsquery
---------------+------------
 'postgradu':1 | 'postgr':*

o que corresponde à forma cortada de postgraduate.

8.11.3. tsvector versus tsquery #

Seção escrita pelo tradutor, não fazendo parte da documentação original.

Exemplo 8.14. Exemplo do tradutor

Este exemplo verifica a correspondência entre os tipos de dados tsvector e tsquery, usando a função to_tsvector, que converte um texto no tipo de dados tsvector, e a função to_tsquery, que converte um texto no tipo de dados tsquery.

SELECT to_tsvector('portuguese', 'absoluto' ),
       to_tsquery('portuguese', 'absolutamente' );
 to_tsvector | to_tsquery
-------------+------------
 'absolut':1 | 'absolut'
SELECT to_tsvector('portuguese', 'absoluto' )
    @@ to_tsquery('portuguese', 'absolutamente' );
 ?column?
----------
 t
-- Em português esta comparação resultou em verdade,
-- mas em inglês esta comparação resulta em falso,
-- como visto abaixo.

SELECT to_tsvector('english', 'absoluto' ),
       to_tsquery('english', 'absolutamente' );
 to_tsvector  |   to_tsquery
--------------+----------------
 'absoluto':1 | 'absolutament'
SELECT to_tsvector('english', 'absoluto' )
    @@ to_tsquery('english', 'absolutamente' );
 ?column?
----------
 f



[49] lexema: Conjunto de palavras de mesma classe morfológica que diferem entre si por sufixos reflexivos. Fonte: Dicionário inFormal. (N. T.)

[50] lexema: Unidade linguística que combina a forma (gráfica ou fonética) e o significado, o qual não é divisível em unidades menores; unidade lexical; Do grego lẽxis, «vocábulo». Fonte: infopédia (N. T.)