12.8. Тестирование и отладка текстового поиска#
12.8. Тестирование и отладка текстового поиска #
Поведение пользовательской конфигурации текстового поиска может легко стать запутанным. Функции, описанные в этом разделе, полезны для тестирования объектов текстового поиска. Вы можете протестировать полную конфигурацию или отдельно протестировать парсеры и словари.
12.8.1. Тестирование конфигурации #
Функция ts_debug позволяет легко тестировать конфигурацию полнотекстового поиска.
ts_debug([configregconfig, ]documenttext, OUTaliastext, OUTdescriptiontext, OUTtokentext, OUTdictionariesregdictionary[], OUTdictionaryregdictionary, OUTlexemestext[]) returns setof record
ts_debug отображает информацию о каждом компоненте
документа, созданном парсером и обработанным
настроенными словарями. Он использует
конфигурацию, указанную в config,
или default_text_search_config, если этот аргумент не указан.
ts_debug возвращает одну строку для каждого компонента, идентифицированного парсером в тексте. Возвращаемые столбцы:
aliastext— краткое название типа компонентаdescriptiontext— описание типа компонентаtokentext— текст компонентаdictionariesregdictionary[]— словари, выбранные конфигурацией для данного типа компонентаdictionaryregdictionary— словарь, который распознал компонент, илиNULL, если ни один не распозналlexemestext[]— лексема(ы), произведенные словарем, который распознал компонент, или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_nametext,documenttext, OUTtokidinteger, OUTtokentext) returnssetof recordts_parse(parser_oidoid,documenttext, OUTtokidinteger, OUTtokentext) returnssetof 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_nametext, OUTtokidinteger, OUTaliastext, OUTdescriptiontext) returnssetof recordts_token_type(parser_oidoid, OUTtokidinteger, OUTaliastext, OUTdescriptiontext) returnssetof 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(dictregdictionary,tokentext) returnstext[]
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'