PostgreSQL proporciona dos tipos de datos que
están diseñados para soportar la búsqueda de texto completo, que es la actividad de
buscar a través de una colección de documentos en lenguaje natural
para localizar aquellos que mejor coincidan con una consulta.
El tipo tsvector representa un documento en una forma optimizada
para la búsqueda de texto; el tipo tsquery representa de manera similar
una consulta de texto.
La Chapter 12 proporciona una explicación detallada de esta
facilidad, y la Section 9.13 resume las
funciones y operadores relacionados.
tsvector #
Un valor tsvector es una lista ordenada de
lexemas distintos, que son palabras que han sido
normalizadas para fusionar diferentes variantes de la misma palabra
(consulta la Chapter 12 para más detalles). La ordenación y
la eliminación de duplicados se realizan automáticamente durante la entrada, como se muestra en
este ejemplo:
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 que contienen espacios en blanco o puntuación, rodéalos con comillas:
SELECT $$the lexeme ' ' contains spaces$$::tsvector;
tsvector
-------------------------------------------
' ' 'contains' 'lexeme' 'spaces' 'the'
(Utilizamos literales de cadena delimitados por dólares en este ejemplo y en el siguiente para evitar la confusión de tener que duplicar las comillas dentro de los literales). Las comillas incrustadas y las barras invertidas deben duplicarse:
SELECT $$the lexeme 'Joe''s' contains a quote$$::tsvector;
tsvector
------------------------------------------------
'Joe''s' 'a' 'contains' 'lexeme' 'quote' 'the'
Opcionalmente, se pueden adjuntar posiciones enteras a los 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
Una posición normalmente indica la ubicación de la palabra de origen en el documento. La información posicional se puede utilizar para la clasificación por proximidad. Los valores de posición pueden variar de 1 a 16383; los números mayores se establecen silenciosamente en 16383. Las posiciones duplicadas para el mismo lexema se descartan.
Los lexemas que tienen posiciones pueden etiquetarse además con un
peso, que puede ser A,
B, C o D.
D es el valor predeterminado y, por lo tanto, no se muestra en la salida:
SELECT 'a:1A fat:2B,4C cat:5D'::tsvector;
tsvector
----------------------------
'a':1A 'cat':5 'fat':2B,4C
Los pesos se utilizan normalmente para reflejar la estructura del documento, por ejemplo marcando las palabras del título de manera diferente a las palabras del cuerpo. Las funciones de clasificación de búsqueda de texto pueden asignar diferentes prioridades a los diferentes marcadores de peso.
Es importante entender que el propio
tipo tsvector no realiza ninguna normalización
de palabras; asume que las palabras que se le dan están normalizadas
apropiadamente para la aplicación. Por ejemplo,
SELECT 'The Fat Rats'::tsvector;
tsvector
--------------------
'Fat' 'Rats' 'The'
Para la mayoría de las aplicaciones de búsqueda de texto en inglés, las palabras anteriores se
considerarían no normalizadas, pero a tsvector no le importa.
El texto del documento original normalmente debe pasarse a través de
to_tsvector para normalizar las palabras de manera apropiada
para la búsqueda:
SELECT to_tsvector('english', 'The Fat Rats');
to_tsvector
-----------------
'fat':2 'rat':3
Nuevamente, consulta la Chapter 12 para obtener más detalles.
tsquery #
Un valor tsquery almacena los lexemas que se van a
buscar, y los puede combinar utilizando los operadores booleanos
& (AND), | (OR), y
! (NOT), así como el operador de búsqueda de frases
<-> (SEGUIDO POR). También hay una variante
< del operador SEGUIDO POR,
donde N>N es una constante entera que
especifica la distancia entre los dos lexemas que se están buscando.
<-> es equivalente a <1>.
Se pueden usar paréntesis para forzar la agrupación de estos operadores.
En ausencia de paréntesis, ! (NOT) se asocia con mayor fuerza,
luego <-> (SEGUIDO POR), después
& (AND), siendo | (OR) el que se
asocia con menor fuerza.
Aquí tienes algunos ejemplos:
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, los lexemas en un tsquery se pueden etiquetar con
una o más letras de peso, lo que los restringe a coincidir solo con
lexemas de tsvector con uno de esos pesos:
SELECT 'fat:ab & cat'::tsquery;
tsquery
------------------
'fat':AB & 'cat'
Además, los lexemas en un tsquery se pueden etiquetar con *
para especificar la coincidencia de prefijos:
SELECT 'super:*'::tsquery; tsquery ----------- 'super':*
Esta consulta coincidirá con cualquier palabra en un tsvector que comience
con “super”.
Las reglas de entrecomillado para los lexemas son las mismas descritas anteriormente para
los lexemas en tsvector; y, al igual que con tsvector,
cualquier normalización requerida de las palabras debe realizarse antes de convertirlas
al tipo tsquery. La función to_tsquery
es conveniente para realizar dicha normalización:
SELECT to_tsquery('Fat:ab & Cats');
to_tsquery
------------------
'fat':AB & 'cat'
Ten en cuenta que to_tsquery procesará los prefijos de la misma manera
que otras palabras, lo que significa que esta comparación devuelve verdadero:
SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' ); ?column? ---------- t
porque postgres se reduce (stemmed) a postgr:
SELECT to_tsvector( 'postgraduate' ), to_tsquery( 'postgres:*' ); to_tsvector | to_tsquery ---------------+------------ 'postgradu':1 | 'postgr':*
lo cual coincidirá con la forma reducida de postgraduate.