Привет, Хабр!

Сегодня предлагаю обсудить 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 методам, в следующем посте перейдём к использованию языковых моделей, ну а на сегодня у меня все. Надеюсь, эта информация оказалась для вас полезной. Если остались вопросы по коду или настройке — спрашивайте в комментариях.

Спасибо за внимание!

Комментарии (0)