Top.Mail.Ru

Полнотекстовый поиск релевантных значений с помощью Elasticsearch

Что такое Elasticsearch

Elasticsearch — это рас­пре­делен­ная система поиска и ана­лити­ки данных, ос­но­ван­ная на Apache Lucene. Она от­ли­ча­ет­ся высокой про­из­во­дитель­ностью, мас­шта­биру­емостью и гиб­костью при работе с большими объемами данных.

Кому может быть полезна статья

  1. Раз­ра­бот­чи­кам, которые ис­поль­зу­ют или пла­ниру­ют ис­поль­зо­вать Elasticsearch для пол­но­тек­сто­вого поиска в своих проектах.

  2. Иссле­дова­телям, которым ин­те­рес­ны методы и подходы к пол­но­тек­сто­вому поиску с ис­поль­зо­вани­ем Elasticsearch.

  3. Ана­лити­кам, которые работают с большими объемами тек­сто­вых данных и хотят на­учить­ся эф­фектив­но искать ре­леван­тные значения.

  4. Бизнес-ана­лити­кам и вла­дель­цам пред­при­ятий, которые хотят улучшить поиск и на­вига­цию по своим данным для лучшего по­нима­ния поль­зо­ватель­ских пот­ребнос­тей и тре­бова­ний.

  5. Сту­ден­там и ака­деми­чес­ким ра­бот­ни­кам, которые изучают ин­форма­ци­он­ный поиск и хотят поз­на­комить­ся с при­мене­ни­ем Elasticsearch для решения задач пол­но­тек­сто­вого поиска.

Автор статьи не пре­тен­ду­ет на бе­зого­вороч­ное эк­спертное мнение в области работы с Elasticsearch, всё на­писан­ное ниже является субъ­ек­тивным опытом.

Рас­смат­ри­ва­емый способ не привязан к какому-то кон­крет­но­му языку прог­рамми­рова­ния, но примеры в статье будут рас­смот­ре­ны в кон­тек­сте работы с PHP.

Чем может быть полезен Elasticsearch

Elasticsearch может быть полезен для разных типов ор­га­низа­ций и проектов. Вот не­кото­рые примеры:

  1. Поиск и ин­декса­ция. Elasticsearch может ис­поль­зо­ваться для вы­пол­не­ния сложных по­ис­ко­вых запросов и быстрого доступа к струк­ту­риро­ван­ной, пол­но­тек­сто­вой и ге­ог­ра­фичес­кой ин­форма­ции. Он может быть ис­поль­зо­ван для создания по­ис­ко­вых движков для веб-сайтов, систем уп­равле­ния кон­тентом, журналов и многого другого.

  2. Жур­на­лиро­вание и анализ логов. Elasticsearch поз­во­ля­ет собирать, хранить и ана­лизи­ровать большие объемы журналов и событий. Он может помочь от­сле­дить проблемы, мо­нито­рить про­из­во­дитель­ность и обес­пе­чивать бе­зопас­ность в режиме ре­аль­но­го времени.

  3. Бизнес-ана­лити­ка. Elasticsearch под­держи­ва­ет аг­ре­гиро­вание и анализ данных, что делает его полезным для вы­пол­не­ния сложных запросов и создания ди­нами­чес­ких отчетов и графиков. Он может быть применен для решения таких задач, как мо­нито­ринг мар­ке­тин­го­вых кампаний, анализ вза­имо­дей­ствия с поль­зо­вате­лями и прог­но­зиро­вание рынков.

  4. Машинное обучение. Elasticsearch может быть ин­тегри­рован с другими инс­тру­мен­та­ми ма­шин­но­го обучения, что поз­во­ля­ет про­водить анализ данных в реальном времени и обучать модели.

 

Рабочая среда

Для начала пред­ста­вим, что в рабочей среде уже ус­та­нов­лен и настроен Elasticsearch хотя бы от 7-й версии:
- Почему от 7-й?
- Потому что начиная с 7-й версии раз­ра­бот­чи­ки зна­читель­но улучшили оп­ти­миза­цию, бла­года­ря чему «Эластик» стал менее «про­жор­ли­вым» до RAM.

 

Контекст задачи

Ре­али­зация пол­но­тек­сто­вого поиска по поль­зо­вате­лям и проектам с выдачей ре­леван­тных ре­зуль­та­тов.

 

Обзор свойств и настроек ин­декса­тора

mappings — это процесс оп­ре­деле­ния, как поля до­кумен­та должны быть сох­ра­нены и ин­декси­рова­ны в индексе Elasticsearch. Он опи­сыва­ет струк­ту­ру данных, оп­ре­деля­ет типы полей (стро­ковые, числовые, даты и т. д.) и их ха­рак­те­рис­ти­ки (ана­лиза­торы, ин­декси­рова­ние и хранение данных).

В этом коде оп­ре­деля­ется схема индекса (mappings) для поля name. Внутри схемы указано, что тип поля — text, это означает, что текст будет ана­лизи­роваться перед ин­декси­рова­нием.

Также указан ана­лиза­тор name_analyzer, который будет при­менять­ся к тексту при ин­декси­рова­нии и поиске данных. Ана­лиза­тор оп­ре­деля­ет, как текст будет раз­би­вать­ся на от­дель­ные токены, какие фильтры будут при­менять­ся и так далее.

Допол­ни­тель­но указано, что для поля 'name' будет создано еще одно подполе keyword с типом keyword. Подполе keyword будет со­дер­жать не­ана­лизи­рован­ную (ори­гиналь­ную) версию значения поля name.

Такая струк­ту­ра mappings поз­во­ля­ет вы­пол­нять раз­личные операции с тек­сто­выми данными, в том числе пол­но­тек­сто­вый поиск и поиск по ключевым словам.

settings — это па­рамет­ры кон­фи­гура­ции, которые оп­ре­деля­ют по­веде­ние и ха­рак­те­рис­ти­ки индекса или кластера. Нас­трой­ки включают в себя па­рамет­ры, такие как ко­личес­тво реплик, ко­личес­тво шардов, ана­лиза­торы, фильтры и другие опции, которые влияют на процесс ин­декси­рова­ния и поиска данных.

В этом участке кода оп­ре­деля­ется секция analysis в нас­трой­ках Elasticsearch-индекса. Внутри секции analysis оп­ре­деле­ны две под­секции: analyzer и filter.

В под­секции analyzer оп­ре­делен ана­лиза­тор с именем name_analyzer. Ана­лиза­тор имеет тип custom, это означает, что его па­рамет­ры можно нас­тро­ить са­мос­то­ятель­но. В данном случае ана­лиза­тор ис­поль­зу­ет то­кени­затор standard, который раз­би­ва­ет текст на токены на основе стан­дар­тных правил раз­би­ения для ан­глий­ско­го языка. Далее при­меня­ют­ся два фильтра: lowercase, который приводит все токены к нижнему регистру, и ngram, который раз­би­ва­ет токены на все воз­можные подс­тро­ки фик­си­рован­ной длины (от одного до 20 символов). Таким образом, ана­лиза­тор раз­би­ва­ет текст на токены и создает n-граммы для каждого токена.

В под­секции filter оп­ре­делен фильтр с именем ngram'. Этот фильтр имеет тип ngram и нас­тра­ива­ет­ся с па­рамет­ра­ми min_gram и max_gram. Параметр min_gram ука­зыва­ет ми­нималь­ную длину n-граммы, а max_gram — мак­си­маль­ную. В данном случае ус­та­нов­лены значения 1 и 20 со­от­ветс­твен­но, это означает, что будут соз­да­вать­ся n-граммы от одного символа до 20.

Таким образом, секция analysis оп­ре­деля­ет ана­лиза­тор name_analyzer, который будет ис­поль­зо­ваться для раз­би­ения текста на токены и создания n-грамм. Этот ана­лиза­тор будет при­менять­ся при ин­декси­рова­нии и поиске данных для поля name в Elasticsearch-индексе.

Обзор свойств запроса

В этом коде оп­ре­деля­ется поиск в индексе по полю name. В секции query ис­поль­зу­ется булев оператор should, который ука­зыва­ет, что ре­зуль­та­ты поиска могут со­от­ветс­тво­вать любому из ука­зан­ных условий.

Первое условие ис­поль­зу­ет match_phrase_prefix, что означает, что будет искаться точное со­от­ветс­твие запросу с воз­можностью пре­фик­сно­го сов­па­дения. В данном случае поле name должно точно со­от­ветс­тво­вать запросу с воз­можностью пре­фик­сно­го сов­па­дения с до­пус­ти­мым рас­сто­яни­ем slop, равным 2.

Второе условие ис­поль­зу­ет match, и это означает, что будет искаться сов­па­дение запроса с полем name без пре­фик­сно­го сов­па­дения.

Таким образом, код оп­ре­деля­ет, что в индексе про­водит­ся поиск по полю name с ис­поль­зо­вани­ем двух условий: точного со­от­ветс­твия с воз­можностью пре­фик­сно­го сов­па­дения и сов­па­дения без префикса.

Резуль­та­ты

После пе­ре­ин­декса­ции данных поиск стал выдавать ожи­да­емые ре­зуль­та­ты, к примеру:

Список запросов для поиска поль­зо­вате­лей с Ф. И. О. Ахед­жа­кова Лия и Крамаров Савелий:

Для Лии:

Лия А*

А* Лия

Ахед­жа­кова Лия

Ахедж* Л*

в данном случае ком­би­наций будет большое ко­личес­тво

Для Савелия:

Савелий К

К Савелий

К* Са*

* - означает любое ко­личес­тво символов