12.8. Тестирование и отладка текстового поиска#

12.8. Тестирование и отладка текстового поиска

12.8. Тестирование и отладка текстового поиска #

Поведение пользовательской конфигурации текстового поиска может легко стать запутанным. Функции, описанные в этом разделе, полезны для тестирования объектов текстового поиска. Вы можете протестировать полную конфигурацию или отдельно протестировать парсеры и словари.

12.8.1. Тестирование конфигурации #

Функция ts_debug позволяет легко тестировать конфигурацию полнотекстового поиска.

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

ts_debug отображает информацию о каждом компоненте документа, созданном парсером и обработанным настроенными словарями. Он использует конфигурацию, указанную в config, или default_text_search_config, если этот аргумент не указан.

ts_debug возвращает одну строку для каждого компонента, идентифицированного парсером в тексте. Возвращаемые столбцы:

  • alias text — краткое название типа компонента

  • description text — описание типа компонента

  • token text — текст компонента

  • dictionaries regdictionary[] — словари, выбранные конфигурацией для данного типа компонента

  • dictionary regdictionary — словарь, который распознал компонент, или NULL, если ни один не распознал

  • lexemes text[] — лексема(ы), произведенные словарем, который распознал компонент, или NULL, если ни один из них не распознал; пустой массив ({}) означает, что компонент был распознан как стоп-слово

Вот простой пример:

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}

Для более подробной демонстрации мы сначала создадим конфигурацию public.english и словарь Ispell для английского языка.

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 * FROM ts_debug('public.english', 'The Brightest supernovaes');
   alias   |   description   |    token    |         dictionaries          |   dictionary   |   lexemes
-----------+-----------------+-------------+-------------------------------+----------------+-------------
 asciiword | Word, all ASCII | The         | {english_ispell,english_stem} | english_ispell | {}
 blank     | Space symbols   |             | {}                            |                |
 asciiword | Word, all ASCII | Brightest   | {english_ispell,english_stem} | english_ispell | {bright}
 blank     | Space symbols   |             | {}                            |                |
 asciiword | Word, all ASCII | supernovaes | {english_ispell,english_stem} | english_stem   | {supernova}

В этом примере слово Brightest было распознано парсером как ASCII word (псевдоним asciiword). Для этого типа компонента список словарей включает english_ispell и english_stem. Слово было распознано словарем english_ispell, который сократил его до существительного bright. Слово supernovaes неизвестно словарю english_ispell, поэтому оно было передано следующему словарю и, к счастью, было распознано (на самом деле, english_stem - это словарь Snowball, который распознает все; поэтому он был помещен в конец списка словарей).

Слово The было распознано словарем english_ispell как стоп-слово (Раздел 12.6.1) и не будет проиндексировано. Пробелы также отбрасываются, так как конфигурация не предоставляет словарей для них.

Вы можете уменьшить ширину вывода, явно указав, какие столбцы нужно видеть:

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}

12.8.2. Тестирование парсера #

Следующие функции позволяют прямое тестирование парсера текстового поиска.

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

ts_parse разбирает данный document и возвращает серию записей, по одной для каждого компонента, полученного при разборе. Каждая запись включает tokid, показывающий присвоенный тип компонента, и token, который является текстом компонента. Например:

SELECT * FROM ts_parse('default', '123 - a number');
 tokid | token
-------+--------
    22 | 123
    12 |
    12 | -
     1 | a
    12 |
     1 | number

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

ts_token_type возвращает таблицу, которая описывает каждый тип компонента, который указанный парсер может распознать. Для каждого типа компонента, таблица содержит целое число tokid, которое парсер использует для маркировки компонента этого типа, alias, который называет тип компонента в командах конфигурации, и краткое description. Например:

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

12.8.3. Тестирование словаря #

Функция ts_lexize облегчает тестирование словаря.

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

ts_lexize возвращает массив лексем, если входной компонент token известен словарю, или пустой массив, если компонент известен словарю, но является стоп-словом, или NULL, если это неизвестное слово.

Примеры:

SELECT ts_lexize('english_stem', 'stars');
 ts_lexize
-----------
 {star}

SELECT ts_lexize('english_stem', 'a');
 ts_lexize
-----------
 {}

Примечание

Функция ts_lexize ожидает один компонент, а не текст. Вот случай, когда это может вызвать путаницу:

SELECT ts_lexize('thesaurus_astro', 'supernovae stars') is null;
 ?column?
----------
 t

Тезаурусный словарь thesaurus_astro знает фразу supernovae stars, но ts_lexize не справляется, так как он не разбирает входной текст, а обрабатывает его как один компонент. Используйте plainto_tsquery или to_tsvector для тестирования тезаурусных словарей, например:

SELECT plainto_tsquery('supernovae stars');
 plainto_tsquery
-----------------
 'sn'