Словари используются для исключения слов, которые не должны учитываться при поиске (стоп-слова), а также для того, чтобы нормализовать слова, обеспечивая сопоставление различных производных форм одного и того же слова. Успешно нормализованное слово называется лексема. Помимо повышения качества поиска, процессы нормализации и удаления стоп-слов позволяют уменьшить размер tsvector представления документа, тем самым
увеличивая производительность. Нормализация не всегда имеет лингвистическое значение и, как правило, зависит от семантики приложения.
Примеры нормализации:
Лингвистическая — словари Ispell обеспечивают приведение входных слов к нормализованной форме; словари стеммеров удаляют окончания слов
URL адреса местоположений могут быть канонизированы для обеспечения сопоставления эквивалентных URL-адресов:
http://www.pgsql.ru/db/mw/index.html
http://www.pgsql.ru/db/mw/
http://www.pgsql.ru/db/../db/mw/index.html
Названия цветов могут быть заменены их шестнадцатеричными значениями, например:
red, green, blue, magenta -> FF0000, 00FF00, 0000FF, FF00FF
При индексировании чисел можно сократить количество дробных разрядов для уменьшения диапазона возможных значений; так, например, 3.14159265359, 3.1415926, 3.14 будут идентичны после нормализации, если после десятичной запятой сохраняются только два знака.
Словарь представляет собой программу, которая принимает токен в качестве входных данных и возвращает:
массив лексем, если входной токен известен словарю (обратите внимание, что один токен может порождать несколько лексем)
одну лексему с установленным TSL_FILTER флагом для замены
исходного токена новым токеном, который будет передан последующим
словарям (словарь, выполняющий такие действия, называется
фильтрующим словарем)
пустой массив, если токен известен словарю, но является стоп-словом
NULL NULL, если словарь не распознает входной токен
Digital Q.DataBase предоставляет предопределенные словари для многих языков. Также имеется несколько предопределенных шаблонов, которые могут быть использованы для создания новых словарей с пользовательскими параметрами. Каждый предопределенный шаблон словаря описан ниже. Если ни один из существующих
шаблонов не подходит, возможно создание новых; см.
contrib/ соответствующий раздел Digital Q.DataBase дистрибутива
для ознакомления с примерами.
Конфигурация текстового поиска связывает парсер с набором словарей для обработки выходных токенов парсера. Для каждого типа токенов, которые может возвращать парсер, в конфигурации определяется отдельный список словарей. Когда парсер обнаруживает токен соответствующего типа, выполняется последовательное обращение к каждому словарю из списка до тех пор, пока один из них не идентифицирует его как известное слово. Если токен идентифицируется
как стоп-слово или если ни один словарь не распознает токен, он будет
отброшен и не будет включен в индекс или использован при поиске.
Обычно первый словарь, возвращающий не-NULL
пустой результат, определяет итоговое значение, а обращение к оставшимся словарям не производится; однако фильтрующий словарь может заменить исходное слово
измененным, которое затем передается последующим словарям.
Общее правило настройки списка словарей заключается в том, чтобы сначала указать наиболее узкоспециализированный словарь, затем более общие словари и в конце — универсальный словарь, такой как Snowball стеммер или simple, который
распознает любые типы данных. Например, для поиска в области астрономии
(соответствующаяastro_en конфигурация текстового поиска) можно сопоставить тип токена
asciiword (слово в кодировке ASCII) со словарем синонимов астрономических терминов, общим английским словарем и Snowball английским
стеммером:
ALTER TEXT SEARCH CONFIGURATION astro_en
ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem;
Фильтрующий словарь может быть размещен в любой позиции списка, кроме последней, где его применение было бы нецелесообразным. Фильтрующие словари полезны для частичной нормализации слов, что упрощает дальнейшую обработку последующими словарями. Например, фильтрующий словарь может применяться для удаления диакритических знаков из символов, аналогично тому, как это реализовано в unaccent модуле.
Стоп-слова — это крайне распространенные слова, которые встречаются практически в каждом документе и не обладают поисковой ценностью. Следовательно, их можно игнорировать
в контексте полнотекстового поиска. Например, любой англоязычный текст
содержит такие слова, как a и the, поэтому их хранение в индексе нецелесообразно. Тем не менее, стоп-слова влияют на позиции в tsvector, что в свою очередь влияет на ранжирование:
SELECT to_tsvector('english', 'in the list of stop words');
to_tsvector
----------------------------
'list':3 'stop':5 'word':6
Позиции 1, 2 и 4 отсутствуют из-за исключения стоп-слов. Значения ранга, вычисленные для документов с использованием стоп-слов и без них, существенно различаются:
SELECT ts_rank_cd (to_tsvector('english', 'in the list of stop words'), to_tsquery('list & stop'));
ts_rank_cd
------------
0.05
SELECT ts_rank_cd (to_tsvector('english', 'list stop words'), to_tsquery('list & stop'));
ts_rank_cd
------------
0.1
Метод обработки стоп-слов определяется конкретным словарем. Например,
ispell словари сначала выполняют нормализацию слов и только затем сверяются со списком стоп-слов, тогда как Snowball стеммеры
сначала проверяют список стоп-слов. Причиной различия в поведении является попытка снижения уровня информационного шума.
Оператор simple шаблон словаря функционирует путем приведения входного токена к нижнему регистру и его сопоставления с содержимым файла стоп-слов. Если токен обнаруживается в файле, возвращается пустой массив, что приводит к исключению данного токена. В противном случае форма слова в нижнем регистре возвращается в качестве нормализованной лексемы. Кроме того, словарь может быть сконфигурирован для передачи нераспознанных слов, не являющихся стоп-словами, следующему словарю в списке.
Ниже приведен пример определения словаря с использованием simple
шаблона:
CREATE TEXT SEARCH DICTIONARY public.simple_dict (
TEMPLATE = pg_catalog.simple,
STOPWORDS = english
);
Здесь english является базовым именем файла стоп-слов.
Полное имя файла будет
$SHAREDIR/tsearch_data/english.stop,
где $SHAREDIR означает
Digital Q.DataBase каталог общих данных (shared-data) текущей установки,
часто /usr/local/share/postgresql (используйте pg_config
--sharedir для его определения, если вы не уверены). Формат файла представляет собой простой список слов, по одному на строку. Пустые строки и завершающие пробелы игнорируются, а символы верхнего регистра приводятся к нижнему; иная обработка содержимого файла не производится.
Теперь можно протестировать созданный словарь:
SELECT ts_lexize('public.simple_dict', 'YeS');
ts_lexize
-----------
{yes}
SELECT ts_lexize('public.simple_dict', 'The');
ts_lexize
-----------
{}
Также можно настроить возврат значения NULLвместо слова в нижнем регистре, если оно не было найдено в файле стоп-слов. Данное поведение определяется путем установки для словаря параметра Accept в значение
false. Продолжение примера:
ALTER TEXT SEARCH DICTIONARY public.simple_dict ( Accept = false );
SELECT ts_lexize('public.simple_dict', 'YeS');
ts_lexize
-----------
SELECT ts_lexize('public.simple_dict', 'The');
ts_lexize
-----------
{}
При использовании значения по умолчанию для параметра Accept = true,
данный словарь целесообразно размещать в simple самом конце
списка словарей, так как он не передает токены
последующим словарям. И наоборот, Accept = false
эффективен только в том случае, если после него в списке указан как минимум еще один словарь.
Большинство типов словарей используют конфигурационные файлы, например, файлы стоп-слов. Данные файлы должны храниться в кодировке UTF-8. При считывании сервером их содержимое автоматически преобразуется в текущую кодировку базы данных, если она отличается от UTF-8.
Обычно в рамках сеанса работы с базой данных конфигурационный файл словаря считывается только один раз — при первом обращении к нему. Если вы изменили конфигурационный файл и хотите, чтобы в текущих сеансах принудительно использовалось его новое содержимое, выполните команду ALTER TEXT SEARCH DICTIONARY команда для словаря. Это может быть «фиктивное» обновление, которое фактически не изменяет значения каких-либо параметров.
Данный шаблон словаря используется для создания словарей, заменяющих слово соответствующим синонимом. Фразы не поддерживаются (для этой цели используйте шаблон тезауруса
(Раздел 2.9.6.4) ). Словарь синонимов может использоваться для решения лингвистических проблем, например, чтобы предотвратить приведение английским стеммером слова «Париж» к
«pari». Достаточно добавить строку Paris paris строка в словаре синонимов; поместите ее перед english_stem
соответствующим стеммером. Например:
SELECT * FROM ts_debug('english', 'Paris');
псевдоним | описание | токен | словари | словарь | лексемы
-----------+-----------------+-------+----------------+--------------+---------
asciiword | Слово, все символы ASCII | Париж | {english_stem} | english_stem | {pari}
CREATE TEXT SEARCH DICTIONARY my_synonym (
TEMPLATE = synonym,
SYNONYMS = my_synonyms
);
ALTER TEXT SEARCH CONFIGURATION english
ALTER MAPPING FOR asciiword
WITH my_synonym, english_stem;
SELECT * FROM ts_debug('english', 'Paris');
alias | description | токен | словари | словарь | лексемы
-----------+-----------------+-------+---------------------------+------------+---------
asciiword | Слово, все символы ASCII | Париж | {my_synonym,english_stem} | my_synonym | {paris}
Единственным параметром, необходимым для данного синоним шаблона, является
SYNONYMS, определяющий базовое имя конфигурационного файла
— my_synonyms в приведенном выше примере. Полное имя файла будет
$SHAREDIR/tsearch_data/my_synonyms.syn
(где $SHAREDIR означает
Digital Q.DataBase каталог общих данных установки).
Формат файла представляет собой одну строку
на каждое заменяемое слово, за которым следует соответствующий синоним,
разделенный пробелом. Пустые строки и завершающие пробелы игнорируются.
Оператор синоним данный шаблон также поддерживает необязательный параметр
CaseSensitive, значением по умолчанию для которого является false. Если
CaseSensitive установлен в false, слова в файле синонимов приводятся к нижнему регистру аналогично входным токенам. Если параметр имеет значение
true, слова и токены не приводятся к нижнему регистру,
а сравниваются в исходном виде.
Символ «звездочка» (*) может быть указан в конце синонима
в конфигурационном файле. Это указывает на то, что синоним является префиксом.
Символ «звездочка» игнорируется, когда запись используется в функции
to_tsvector(), но при использовании в функции
to_tsquery(), результатом будет элемент запроса с
маркером поиска по префиксу (см.
Раздел 2.9.3.2).
Например, предположим, что в конфигурационном файле
$SHAREDIR/tsearch_data/synonym_sample.syn:
postgres pgsql postgresql pgsql postgre pgsql gogle googl indices index*
В результате будут получены следующие данные:
mydb=# CREATE TEXT SEARCH DICTIONARY syn (template=synonym, synonyms='synonym_sample');
mydb=# SELECT ts_lexize('syn', 'indices');
ts_lexize
-----------
{index}
(1 row)
mydb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple);
mydb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn;
mydb=# SELECT to_tsvector('tst', 'indices');
to_tsvector
-------------
'index':1
(1 row)
mydb=# SELECT to_tsquery('tst', 'indices');
to_tsquery
------------
'index':*
(1 row)
mydb=# SELECT 'indexes are very useful'::tsvector;
tsvector
---------------------------------
'are' 'indexes' 'useful' 'very'
(1 row)
mydb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst', 'indices');
?column?
----------
t
(1 строка)
Словарь-тезаурус (иногда обозначаемый аббревиатурой TZ) представляет собой совокупность слов, содержащую информацию о связях между словами и фразами, то есть более широкие термины (BT), более узкие термины (NT), предпочтительные, непредпочтительные, родственные термины и так далее.
По существу, словарь-тезаурус заменяет все непредпочтительные термины одним предпочтительным термином и, опционально, сохраняет исходные термины для индексирования. Digital Q.DataBaseТекущая реализация словаря-тезауруса является расширением словаря синонимов с добавленной поддержкой фраз support. Для словаря-тезауруса требуется конфигурационный файл следующего формата:
# это комментарий образцы_слов : индексируемые_слова еще_образцы_слов : еще_индексируемые_слова ...
где символ двоеточия (:) служит разделителем между исходной фразой и ее заменой.
Словарь-тезаурус использует подсловарь (который указывается в конфигурации словаря) для нормализации входного текста перед проверкой совпадений фраз. Допускается выбор только одного
подсловаря. Если подсловарю не удается распознать слово, возвращается ошибка. В этом случае следует либо отказаться от использования данного слова, либо обучить ему подсловарь. Можно поставить символ звездочки (*) в начале индексируемого слова, чтобы пропустить его обработку
подсловарём, однако все слова-образцы должны должны быть известны
подсловарю.
При наличии нескольких фраз, соответствующих входным данным, словарь-тезаурус выбирает наиболее длинное совпадение, а при равной длине используется последнее определение.
Невозможно указать конкретные стоп-слова, распознаваемые подсловарём; вместо этого используйте ? для обозначения позиции, в которой может встретиться любое стоп-слово. Например, если предположить, что a и
the являются стоп-словами согласно подсловарю:
? one ? two : swsw
соответствует a one the two и the one a two;
оба выражения будут заменены на swsw.
Поскольку словарь-тезаурус обладает возможностью распознавания фраз, он должен сохранять свое состояние и взаимодействовать с парсером. Словарь-тезаурус использует данные назначения, чтобы определить, следует ли обрабатывать следующее слово или прекратить накопление. Словарь-тезаурус должен быть сконфигурирован
тщательным образом. Например, если словарю-тезаурусу назначена обработка только asciiword токена, то определение в словаре-тезаурусе вида one 7 не будет работать, так как тип токена
uint не назначен словарю-тезаурусу.
Тезаурусы используются в процессе индексирования, поэтому любое изменение параметров словаря-тезауруса требует переиндексации. Для большинства других типов словарей незначительные изменения, такие как добавление или удаление стоп-слов, не требуют обязательного выполнения переиндексации.
Для определения нового словаря-тезауруса используйте тезаурус
шаблон. Например:
CREATE TEXT SEARCH DICTIONARY thesaurus_simple (
TEMPLATE = thesaurus,
DictFile = mythesaurus,
Dictionary = pg_catalog.english_stem
);
Здесь:
thesaurus_simple — это имя нового словаря
mythesaurus — это базовое имя
файла конфигурации тезауруса.
(Его полное имя будет $SHAREDIR/tsearch_data/mythesaurus.ths,
где $SHAREDIR обозначает каталог общих данных
установки.)
pg_catalog.english_stem — это подсловарь (в данном случае
английский стеммер Snowball) для нормализации в словаре-тезаурусе.
Обратите внимание, что подсловарь будет иметь собственную
конфигурацию (например, стоп-слова), которая здесь не приведена.
После этого можно назначить словарь-тезаурус thesaurus_simple
соответствующим типам токенов в конфигурации текстового поиска, например:
ALTER TEXT SEARCH CONFIGURATION russian
ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
WITH thesaurus_simple;
Рассмотрим простой астрономический тезаурус thesaurus_astro,
содержащий ряд астрономических словосочетаний:
supernovae stars : sn crab nebulae : crab
Ниже приведен пример создания словаря и сопоставления типов токенов с астрономическим тезаурусом и английским стеммером:
CREATE TEXT SEARCH DICTIONARY thesaurus_astro (
TEMPLATE = thesaurus,
DictFile = thesaurus_astro,
Dictionary = english_stem
);
ALTER TEXT SEARCH CONFIGURATION russian
ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
WITH thesaurus_astro, english_stem;
Теперь мы можем рассмотреть принцип работы данного механизма.
ts_lexize малопригодна для тестирования тезауруса,
поскольку она обрабатывает входные данные как единый токен. Вместо этого можно использовать
plainto_tsquery и to_tsvector
которая разбивает входные строки на несколько отдельных токенов:
SELECT plainto_tsquery('supernova star');
plainto_tsquery
-----------------
'sn'
SELECT to_tsvector('supernova star');
to_tsvector
-------------
'sn':1
В принципе, допускается использование to_tsquery при условии заключения
аргумента в кавычки:
SELECT to_tsquery('''supernova star''');
to_tsquery
------------
'sn'
Обратите внимание, что supernova star соответствует сверхновые
звезды в thesaurus_astro поскольку в конфигурации был указан
конкретный english_stem стеммер в определении тезауруса.
Данный стеммер удалил символ e и s.
Для индексации как исходной фразы, так и подстановки, достаточно включить ее в правую часть определения:
сверхновые звезды : sn сверхновые звезды
SELECT plainto_tsquery('supernova star');
plainto_tsquery
-----------------------------
'sn' & 'supernova' & 'star'
Оператор Ispell шаблон словаря поддерживает
морфологические словари, позволяющие нормализовать различные лингвистические формы слова, приводя их к единой лексеме. Например,
английский Ispell словарь может сопоставлять все словоформы поискового термина bank, такие как
banking, banked, banks,
banks', а также bank's.
Стандартный Digital Q.DataBase дистрибутив системы не содержит Ispell конфигурационных файлов. Словари для множества языков доступны в Ispell. Кроме того, поддерживаются некоторые более современные форматы файлов словарей — MySpell (OO < 2.0.1) и Hunspell (OO >= 2.0.2). Обширный список словарей доступен на OpenOffice Wiki.
Для создания Ispell словаря выполните следующие шаги:
загрузите конфигурационные файлы словаря. OpenOffice
файлы расширений используют .oxt расширение. Необходимо
извлечь .aff и .dic файлы и изменить
их расширения на .affix и .dict. Для некоторых файлов словарей также необходимо выполнить преобразование кодировки символов в UTF-8 с помощью специальных команд (например, для словаря норвежского языка):
iconv -f ISO_8859-1 -t UTF-8 -o nn_no.affix nn_NO.aff iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic
скопируйте файлы в $SHAREDIR/tsearch_data каталог
загрузите файлы в Digital Q.DataBase, используя следующую команду:
CREATE TEXT SEARCH DICTIONARY english_hunspell (
TEMPLATE = ispell,
DictFile = en_us,
AffFile = en_us,
Stopwords = english);
Здесь DictFile, AffFile, а также StopWords
задают базовые имена файлов словаря, аффиксов и стоп-слов.
Файл стоп-слов имеет тот же формат, который был описан выше для
simple тип словаря. Формат остальных файлов в данном документе не специфицирован, однако он представлен на вышеупомянутых веб-сайтах.
Словари Ispell обычно распознают ограниченный набор слов, поэтому за ними должен следовать другой, более универсальный словарь; например, словарь Snowball, который распознает любые последовательности символов.
Оператор .affix файл Ispell имеет следующую
структуру:
prefixes
flag *A:
. > RE # Например: enter > reenter
suffixes
flag T:
E > ST # Например: late > latest
[^AEIOU]Y > -Y,IEST # Например: dirty > dirtiest
[AEIOU]Y > EST # Например: gray > grayest
[^EY] > EST # Например: small > smallest
Кроме того, .dict файл имеет следующую структуру:
lapse/ADGRS lard/DGRS large/PRTY lark/MRS
Формат .dict файла:
basic_form/affix_class_name
В .affix файле каждый флаг аффикса описывается в следующем формате:
condition > [-stripping_letters,] adding_affix
Здесь параметр condition имеет формат, аналогичный формату регулярных выражений.
Допускается использование группировок [...] и [^...].
Например, [AEIOU]Y означает, что последняя буква слова
— "y" а предпоследняя буква — "a",
"e", "i", "o" или "u".
[^EY] означает, что последняя буква не является ни "e"
ни "y".
Словари Ispell поддерживают разделение составных слов —
это полезная функциональность.
Обратите внимание, что в файле аффиксов должен быть указан специальный флаг с помощью
compoundwords controlled , помечающей словарные
слова, которые могут участвовать в образовании составных слов:
compoundwords controlled z
Ниже приведены примеры для норвежского языка:
SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent');
{over,buljong,terning,pakk,mester,assistent}
SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk');
{sjokoladefabrikk,sjokolade,fabrikk}
MySpell формат представляет собой подмножество Hunspell.
The .affix файл Hunspell имеет следующую
структуру:
PFX A Y 1 PFX A 0 re . SFX T N 4 SFX T 0 st e SFX T y iest [^aeiou]y SFX T 0 est [aeiou]y SFX T 0 est [^ey]
Первая строка класса аффиксов представляет собой заголовок. Поля правил аффиксов перечисляются после заголовка:
имя параметра (PFX или SFX)
флаг (имя класса аффиксов)
удаление символов в начале (для префикса) или в конце (для суффикса) слова
добавление аффикса
условие, формат которого аналогичен синтаксису регулярных выражений.
Оператор .dict структура файла аналогична .dict файл
Ispell:
larder/M lardy/RT large/RSPMYT largehearted
MySpell не поддерживает составные слова. Hunspell обладает расширенной поддержкой составных слов. В настоящее время Digital Q.DataBase реализует только базовые операции Hunspell по обработке составных слов.
Оператор Snowball Данный шаблон словаря основан на проекте
Мартина Портера, автора популярного алгоритма стемминга Портера
для английского языка. В настоящее время проект Snowball предоставляет алгоритмы стемминга для многих языков (см. сайт
Snowball для получения дополнительных сведений). Каждый алгоритм обеспечивает преобразование различных словоформ в базовую форму или основу (стемму) слова в рамках конкретного языка. Для работы словаря Snowball требуется параметр language
, определяющий используемый алгоритм стемминга; также дополнительно может быть указано
имя файла стоп-слов, содержащего список слов, подлежащих исключению.
(Digital Q.DataBaseСтандартные списки стоп-слов системы PostgreSQL также предоставляются проектом Snowball.) Например, существует встроенное определение, эквивалентное следующему:
CREATE TEXT SEARCH DICTIONARY english_stem (
TEMPLATE = snowball,
Language = english,
StopWords = english
);
Формат файла стоп-слов аналогичен описанному ранее.
Документ Snowball словарь распознает любые слова, независимо от возможности их упрощения, поэтому его следует располагать в конце списка словарей. Данный словарь нецелесообразно размещать перед любым другим словарем, так как токен никогда не пройдет через него к следующему словарю.