...

или внеочередные заметки


Previous Entry Share Next Entry
Новый словарь русского языка для полнотекстового поиска в PostgreSQL
trekking, Himalaya
obartunov
Костя Книжник (Postgres Professional) "подружил" морфологию Коваленко с полнотекстовым поиском в постгресе - https://github.com/postgrespro/rusmorph.

Если кратко, то rusmorph можно использовать для полнотекстового поиска.


Я использовал список русских слов (всего 297951 слов) для того, чтобы сравнить работу этого словаря со встроенным словарем для hunspell-ого словаря, используемого в libreoffice. Установка словаря rusmorph:

USE_PGXS=1 make
USE_PGXS=1 make install

и его активация:

CREATE EXTENSION rusmorph;

Hunspell словарь для русского языка проще всего взять отсюда. После установки расширения появляется словарь russian_hunspell.

Я обработал все слова двумя словарями и результат сохранил в таблице dtest


SELECT id, w,ts_lexize('russian_hunspell', w) AS hspell, ts_lexize('rusmorph', w) AS rusmorph INTO dtest FROM ruwords;
 \d dtest
                Table "public.dtest"
  Column  |  Type   | Collation | Nullable | Default
----------+---------+-----------+----------+---------
 id       | integer |           |          |
 w        | text    |           |          |
 hspell   | text[]  |           |          |
 rusmorph | text[]  |           |



Используемый тип для атрибутов hspell и rusmorph - это текстовый массив, потому что словари могут возвратить несколько нормальных форм для одного слова, например:

select * from dtest where array_length(hspell,1) > 3 limit 1;
  id   |  w   |        hspell         |     rusmorph
-------+------+-----------------------+-------------------
 57777 | душа | {душа,душ,душить,душ} | {душ,душа,душить}
(1 row)


russian_hunspell словарь не распознает (пустой массив) 81759 слов,в то время как rusmorph - 38978. При этом, russian_hunspell имеет 109235 основ, а rusmorph - 101139. Если посмотреть на конкретный пример, то мы видим, что для полноты полнотекстового поиска rusmorph занимается "читерством" с точки зрения грамматики русского языка.

select w,hspell, rusmorph from  dtest where rusmorph = '{сделать}';

      w       |    hspell     | rusmorph
--------------+---------------+-----------
 сделавшие    | {сделавший}   | {сделать}
 сделавшиеся  | {сделавшийся} | {сделать}
 сделавший    | {сделавший}   | {сделать}
 сделавшийся  | {сделавшийся} | {сделать}
 сделавшими   | {сделавший}   | {сделать}
 сделавшись   | {сделаться}   | {сделать}
 сделавших    | {сделавший}   | {сделать}
 сделавшихся  | {сделавшийся} | {сделать}
 сделаем      | {сделать}     | {сделать}
 сделаемся    | {сделаться}   | {сделать}
 сделает      | {сделать}     | {сделать}
 сделаете     | {сделать}     | {сделать}
 сделается    | {сделаться}   | {сделать}
 сделаешь     | {сделать}     | {сделать}
 сделаешься   | {сделаться}   | {сделать}
 сделай       | {сделать}     | {сделать}
 сделайся     | (null)        | {сделать}
 сделайте     | {сделать}     | {сделать}
 сделайтесь   | (null)        | {сделать}
 сделал       | {сделать}     | {сделать}
 сделала      | {сделать}     | {сделать}
 сделалась    | {сделаться}   | {сделать}
 сделали      | {сделать}     | {сделать}
 сделались    | {сделаться}   | {сделать}
 сделало      | {сделать}     | {сделать}
 сделалось    | {сделаться}   | {сделать}
 сделался     | {сделаться}   | {сделать}
 сделан       | {сделанный}   | {сделать}
 сделана      | {сделанный}   | {сделать}
 сделанная    | {сделанный}   | {сделать}
 сделанного   | {сделанный}   | {сделать}
 сделанное    | {сделанный}   | {сделать}
 сделанной    | {сделанный}   | {сделать}
 сделанном    | {сделанный}   | {сделать}
 сделанному   | {сделанный}   | {сделать}
 сделанную    | {сделанный}   | {сделать}
 сделанные    | {сделанный}   | {сделать}
 сделанный    | {сделанный}   | {сделать}
 сделанным    | {сделанный}   | {сделать}
 сделанными   | {сделанный}   | {сделать}
 сделанных    | {сделанный}   | {сделать}
 сделано      | {сделанный}   | {сделать}
 сделаны      | {сделанный}   | {сделать}
 сделать      | {сделать}     | {сделать}
 сделаться    | {сделаться}   | {сделать}
 сделаю       | {сделать}     | {сделать}
 сделаюсь     | {сделаться}   | {сделать}
 сделают      | {сделать}     | {сделать}
 сделаются    | {сделаться}   | {сделать}
 сделав       | {сделать}     | {сделать}
 сделавшая    | {сделавший}   | {сделать}
 сделавшего   | {сделавший}   | {сделать}
 сделавшегося | {сделавшийся} | {сделать}
 сделавшее    | {сделавший}   | {сделать}
 сделавшееся  | {сделавшийся} | {сделать}
 сделавшей    | {сделавший}   | {сделать}
 сделавши     | (null)        | {сделать}
(57 rows)



Так как словарь встроен в код, то для него не нужна стадия инициализации словаря и не требуется дополнительных усилий для экономии памяти. Конечно, принципиальная возможность модификации словаря для hunspell без компиляции кода представляется удобным, но на практике мне ни разу не приходилось этого делать, так что интеграция словарной базы в код вполне может быть оправданным. Russian_hunspell словарь несколько быстрее, 1754 ms против 2290 ms для rusmorph для обработки всех 297951 слов.
Tags: ,

?

Log in