Привет, Хабр!
Сегодня предлагаю обсудить Managed OpenSearch Yandex Cloud. Поговорим о том, как автоматизировать управление кластером, чтобы сократить расходы на разработку, и как улучшить качество поиска на русском языке, используя доступные в сервисе инструменты морфологии.
Некоторые вопросы использования Managed OpenSearch в Yandex Cloud
Managed Open Search в минимальной (неотказоустойчивой) конфигурации стоит около 15 тысяч рублей в месяц.
Для окружения разработки можно останавливать кластер Open Search на ночь, чтобы немного сэкономить. Достаточно просто создать два cron-триггера, вызывающих Cloud Function с payload “start” и ”stop”. Моя Cloud Function на Python использует REST API для остановки и запуска кластера. Функция может получать Bearer token от сервисного аккаунта, под которым она запускается из контекста вызова через context.token["access_token"]}. Сервисному аккаунту функции нужна соответствующая роль для остановки и запуска кластера Open Search. Разумеется, не стоит делать эту функцию публичной. Как вариант, Bash-функция может использовать yc для запуска и остановки кластера. Сказать по правде, не помню, почему я остановился именно на Python. (Кстати, оставляйте комментарии, если интересуют какие-то детали и пояснения.)
Ещё можно сэкономить, отказавшись от публично доступного узла DASHBOARD.Чаще всего в нём используют notebook-like клиент DevTools. Вместо этого запросы можно отправлять на DATA-хосты (включив публичный доступ) с помощью curl-like клиента, например Insomnia или мой любимый. Не забудьте установить хороший пароль и создать пользователей с необходимыми полномочиями!
Кстати, насчёт пароля. Кажется, более правильный способ подключения к кластеру уже предоставлен в UI-консоли управления, но он ещё полностью не задокументирован. Ссылка ведёт на Metadata Hub. Я напишу об этом отдельный пост, когда познакомлюсь с ним.
Лемматизатор
Из интересных плагинов в Yandex Cloud можно упомянуть yandex-lemmer, предоставляющий морфологию русского языка. Это позволяет искать нормальные начальные формы слов вместо посимвольного сравнения. Следующий пост, кстати, будет посвящён альтернативному решению проблемы «поиска по смыслу, а не по буквам».
Тем не менее, если включить yandex lemmer plugin в настройках кластера, можно сравнить его с примитивным стеммером. Выберем наиболее трудные случаи для стеммера. Кстати, мой любимый случай «фланцы–фланец», но, пожалуй, приберегу на следующий раз.
// тест классического алгоритмического стеммера POST /_analyze?filter_path=tokens.token { "tokenizer": "standard", "filter": [ "russian_stem" ], "text": "бежит письмо пеку переоформляющих радио" } // ответ - неправильные стеммы в yaml формате tokens: - token: "беж" - token: "письм" - token: "пек" - token: "переоформля" - token: "рад" // тест лемматизатора с морфологией POST /_analyze?filter_path=tokens.token { "tokenizer": "standard", "filter": [ "yandex_lemmer" ], "text": "бежит письмо пеку переоформляющих радио" } // ответ: морфологически правильные леммы tokens: - token: "бежит" - token: "бежать" - token: "письмо" - token: "пеку" - token: "пек" - token: "печь" - token: "переоформляющих" - token: "переоформлять" - token: "радио"
Как исключить исходные токены из потока, я найти не смог.
Давайте сравним этот лемматизатор с заслуженным морфологическим анализатором hunspell со словарями LibreOffice. К сожалению, пока невозможно использовать hunspell в YC Managed OpenSearch, так как нет возможности скопировать файлы словарей. см. ниж.
Он бесплатно доступен для тех, кто пока не пользуется Managed OpenSearch. Если скопировать ru_RU.aff, ru_RU.dic в каталог config/hunspell/ru_RU на локально запущенном OpenSearch, получим отличное качество стемм (ну или лемм):
GET http://localhost:9200/_analyze?filter_path=tokens.token Content-Type: application/json Accept: application/yaml { "tokenizer": "standard", "filter": [ { "type": "hunspell", "lang": "ru_RU" } ], "text": "бежит пи��ьмо пеку переоформляющих радио" } tokens: - token: "бежать" - token: "письмо" - token: "пек" - token: "печь" - token: "переоформляющий" - token: "радио"
Что ж, отдав должное заслуженным NLP методам, в следующем посте перейдём к использованию языковых моделей, ну а на сегодня у меня все. Надеюсь, эта информация оказалась для вас полезной. Если остались вопросы по коду или настройке — спрашивайте в комментариях.
Спасибо за внимание!
