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.
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.
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
< do operador
FOLLOWED BY, onde N>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.
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