12.8. Teste e depuração da procura de texto completo #

12.8.1. Teste da configuração
12.8.2. Teste do analisador
12.8.3. Teste de dicionário
12.8.4. Exemplo do tradutor

O comportamento de uma configuração de procura de texto completo personalizada pode facilmente se tornar confuso. As funções descritas nesta seção são úteis para testar objetos de procura de texto completo. Pode ser testada toda a configuração, ou serem testados analisadores e dicionários em separado.

12.8.1. Teste da configuração #

A função ts_debug permite testar facilmente uma configuração de procura de texto completo.

ts_debug([ config regconfig, ] document text,
         OUT alias text,
         OUT description text,
         OUT token text,
         OUT dictionaries regdictionary[],
         OUT dictionary regdictionary,
         OUT lexemes text[])
         returns setof record

A função ts_debug mostra informações sobre cada token do argumento document, conforme produzido pelo analisador e processado pelos dicionários configurados. Esta função usa a configuração especificada pelo argumento config, ou pelo parâmetro default_text_search_config, se este argumento for omitido.

A função ts_debug retorna uma linha para cada token identificado no texto pelo analisador. As colunas retornadas são:

  • alias text — nome curto do tipo de token

  • description text — descrição do tipo de token

  • token text — texto do token

  • dictionaries regdictionary[] — os dicionários selecionados pela configuração para esse tipo de token

  • dictionary regdictionary — o dicionário que reconheceu o token, ou NULL se nenhum reconheceu

  • lexemes text[] — o(s) lexema(s) produzido(s) pelo dicionário que reconheceu o token, ou NULL se nenhum reconheceu; uma matriz vazia ({}) significa que foi reconhecido como palavra de parada

A seguir está um exemplo simples:

SELECT * FROM ts_debug('english', 'a fat  cat sat on a mat - it ate a fat rats');

   alias   |   description   | token |  dictionaries  |  dictionary  | lexemes
-----------+-----------------+-------+----------------+--------------+---------
 asciiword | Word, all ASCII | a     | {english_stem} | english_stem | {}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | fat   | {english_stem} | english_stem | {fat}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | cat   | {english_stem} | english_stem | {cat}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | sat   | {english_stem} | english_stem | {sat}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | on    | {english_stem} | english_stem | {}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | a     | {english_stem} | english_stem | {}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | mat   | {english_stem} | english_stem | {mat}
 blank     | Space symbols   |       | {}             |              |
 blank     | Space symbols   | -     | {}             |              |
 asciiword | Word, all ASCII | it    | {english_stem} | english_stem | {}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | ate   | {english_stem} | english_stem | {ate}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | a     | {english_stem} | english_stem | {}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | fat   | {english_stem} | english_stem | {fat}
 blank     | Space symbols   |       | {}             |              |
 asciiword | Word, all ASCII | rats  | {english_stem} | english_stem | {rat}
(24 linhas)

Para uma demonstração mais extensa, foi primeiro criada a configuração public.english, e um dicionário Ispell para o idioma inglês:

CREATE TEXT SEARCH CONFIGURATION public.english ( COPY = pg_catalog.english );

CREATE TEXT SEARCH DICTIONARY english_ispell (
    TEMPLATE = ispell,
    DictFile = english,
    AffFile = english,
    StopWords = english
);

ALTER TEXT SEARCH CONFIGURATION public.english
   ALTER MAPPING FOR asciiword WITH english_ispell, english_stem;
SELECT alias, token, dictionaries, dictionary,  lexemes
FROM ts_debug('public.english', 'The Brightest supernovaes');
   alias   |    token    |         dictionaries          |   dictionary   |   lexemes
-----------+-------------+-------------------------------+----------------+-------------
 asciiword | The         | {english_ispell,english_stem} | english_ispell | {}
 blank     |             | {}                            |                |
 asciiword | Brightest   | {english_ispell,english_stem} | english_ispell | {bright}
 blank     |             | {}                            |                |
 asciiword | supernovaes | {english_ispell,english_stem} | english_stem   | {supernova}
(5 linhas)

Neste exemplo, a palavra Brightest foi reconhecida pelo analisador como ASCII word (alias asciiword). Para este tipo de token, a lista de dicionários é english_ispell e english_stem. A palavra foi reconhecida pelo english_ispell, que a reduziu ao substantivo bright. A palavra supernovaes não foi reconhecida pelo dicionário english_ispell, então foi passada para o próximo dicionário e, felizmente, foi reconhecida (na verdade, english_stem é um dicionário Snowball que reconhece tudo; por isto foi colocado no final da lista de dicionários).

A palavra The foi reconhecida pelo dicionário english_ispell como palavra de parada (Seção 12.6.1), por isso não será indexada. Os espaços também são descartados, porque a configuração não especifica dicionários para eles.

A largura da saída pode ser reduzida especificando explicitamente quais colunas se deseja ver (no exemplo acima foi omitida a coluna description):

SELECT alias, token, dictionary, lexemes
FROM ts_debug('public.english', 'The Brightest supernovaes');

   alias   |    token    |   dictionary   |   lexemes
-----------+-------------+----------------+-------------
 asciiword | The         | english_ispell | {}
 blank     |             |                |
 asciiword | Brightest   | english_ispell | {bright}
 blank     |             |                |
 asciiword | supernovaes | english_stem   | {supernova}
(5 linhas)

12.8.2. Teste do analisador #

As seguintes funções permitem o teste direto de um analisador de procura de texto completo:

ts_parse(parser_name text, document text,
         OUT tokid integer, OUT token text) returns setof record
ts_parse(parser_oid oid, document text,
         OUT tokid integer, OUT token text) returns setof record

A função ts_parse analisa o document fornecido, e retorna uma série de registros, um para cada token produzido pela análise. Cada registro inclui o campo tokid, mostrando o tipo atribuído ao token, e o campo token, que é o texto do token. Por exemplo:

SELECT * FROM ts_parse('default', '123 - a number');

 tokid | token
-------+--------
    22 | 123
    12 |
    12 | -
     1 | a
    12 |
     1 | number
(6 linhas)

ts_token_type(parser_name text, OUT tokid integer,
              OUT alias text, OUT description text) returns setof record
ts_token_type(parser_oid oid, OUT tokid integer,
              OUT alias text, OUT description text) returns setof record

A função ts_token_type retorna uma tabela descrevendo cada tipo de token que o analisador especificado pode reconhecer. Para cada tipo de token, a tabela mostra no campo tokid o número inteiro que o analisador usa para rotular um token deste tipo, mostra no campo alias o nome deste tipo de token nos comandos de configuração e mostra no campo description uma descrição curta deste tipo de token. Por exemplo:

SELECT * FROM ts_token_type('default');

  tokid |      alias      |               description
-------+-----------------+------------------------------------------
     1 | asciiword       | Word, all ASCII
     2 | word            | Word, all letters
     3 | numword         | Word, letters and digits
     4 | email           | Email address
     5 | url             | URL
     6 | host            | Host
     7 | sfloat          | Scientific notation
     8 | version         | Version number
     9 | hword_numpart   | Hyphenated word part, letters and digits
    10 | hword_part      | Hyphenated word part, all letters
    11 | hword_asciipart | Hyphenated word part, all ASCII
    12 | blank           | Space symbols
    13 | tag             | XML tag
    14 | protocol        | Protocol head
    15 | numhword        | Hyphenated word, letters and digits
    16 | asciihword      | Hyphenated word, all ASCII
    17 | hword           | Hyphenated word, all letters
    18 | url_path        | URL path
    19 | file            | File or path name
    20 | float           | Decimal notation
    21 | int             | Signed integer
    22 | uint            | Unsigned integer
    23 | entity          | XML entity
(23 linhas)

12.8.3. Teste de dicionário #

A função ts_lexize facilita o teste de dicionário.

ts_lexize(dict regdictionary, token text) returns text[]

A função ts_lexize retorna uma matriz de lexemas, se o argumento de entrada token for reconhecido pelo dicionário, ou uma matriz vazia, se o token for reconhecido pelo dicionário, mas for uma palavra de parada, ou NULL se for uma palavra desconhecida.

Exemplos:

SELECT ts_lexize('english_stem', 'stars');

 ts_lexize
-----------
 {star}

SELECT ts_lexize('english_stem', 'a');

 ts_lexize
-----------
 {}

Nota

A função ts_lexize espera um único token, e não um texto. A seguir está um caso onde isso pode ser confuso:

SELECT ts_lexize('thesaurus_astro', 'supernovae stars') is null;

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

O dicionário thesaurus_astro conhece a frase supernovae stars, mas a função ts_lexize falha, porque não analisa o texto da entrada, tratando-o como um único token. Deve ser usada a função plainto_tsquery, ou a função to_tsvector, para testar dicionários thesaurus. Por exemplo:

SELECT plainto_tsquery('supernovae stars');

 plainto_tsquery
-----------------
 'sn'

12.8.4. Exemplo do tradutor #

Exemplo 12.6. Teste do dicionário oo3x_pt_pt

Neste exemplo são feitos testes do dicionário usado pelo OpenOffice e pelo LibreOffice oo3x-pt-PT, instalado no PostgreSQL como oo3x_pt_pt, conforme descrito em detalhes no Exemplo 12.5.

Na tabela a seguir estão mostradas as entradas e os respectivos valores retornados pela função ts_lexize, usando o dicionário oo3x_pt_pt. A função ts_lexize retorna uma matriz de lexemas, se o argumento de entrada for reconhecido pelo dicionário, ou uma matriz vazia, se o argumento de entrada for reconhecido pelo dicionário, mas for uma palavra de parada, ou NULL, se o argumento de entrada for uma palavra desconhecida.

Valores retornados por ts_lexize('oo3x_pt_pt', 'Entrada'):

EntradaValor retornado
agrícola{agricultura}
agrónomo{agrónomo}
agrônomoNULL
contrata{contrato,contratar}
contratador{contratador,contratar}
fui{}
lavrador{lavrador,lavrar}
professora{professor,professorar}
trabalhador{trabalhador,trabalhar}
vaga{vaga,vago,vagar}

Como pode ser visto na tabela acima, a palavra agrónomo foi reconhecida pelo dicionário oo3x_pt_pt, mas a palavra agrônomo não, porque é um dicionário de português de Portugal, enquanto a palavra fui foi reconhecida como palavra de parada e, por isso, foi retornada uma matriz vazia. Para algumas entradas a matriz retornada contém mais de um lexema.