В этой небольшой статье я хочу показать как можно реализовать кастомную приоритетную сортировку данных в ElasticSearch с помощью скрипта на языке Painless.
Приведенные примеры написаны на ЯП Golang, поскольку я разрабатываю ПО на этом языке. Также я подразумеваю что у вас в проекте уже есть некая имплементация клиента для Elastic, возможно реализована "обертка" для работы с вашими структурами данных. Сосредоточимся на скрипте и разберем пример его использования.
Painless — это простой и безопасный язык сценариев, разработанный специально для использования с Elasticsearch.
Со спецификацией можно ознакомиться в официальной документации
https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-guide.html
По описанию видно, что синтаксис языка достаточно простой, поддерживает условия, циклы, базовые типы данных, объявление функций, есть возможность передачи параметров в скрипт.
Исходные данные для задачи.
Есть индекс организаций. Организации могут иметь филиал (ParentId - указатель на родительскую организацию). Организации могут быть разных типов (TypeId - ОАО, АО, ООО).
Организации разделены территориально по регионам (RegionId)
Для наглядности я приведу пример структуры на Golang
![](https://habrastorage.org/getpro/habr/upload_files/d74/ab5/375/d74ab53756b3531ef6261122e86f9f27.jpg)
Задача по сортировке данных может звучать следующим образом.
Сначала вывести все филиалы конкретной организации, например ParentId = 1
, затем должны следовать организации с типом TypeId = 2
, после этого все организации региона , например RegionId = 4
, после этого все организации региона , например RegionId = 3
, а затем все остальные организации.
Пример выдуман лишь для наглядности, но с аналогичной задачей я столкнулся в работе.
Правильно поставленная задача - половина её решения
По условию задачи видно, что нужна пользовательская приоретизация результатов поиска.
Давайте я приведу полный текст скрипта и способ его использования, а затем дам подробное описание.
![](https://habrastorage.org/getpro/habr/upload_files/237/d24/37d/237d2437da2c7e5f30e5574dfb444217.jpg)
PS: Здесь не привожу пример запроса query
.
Видим что задача решается в 3 действия.
1. Имплементация скрипта.
2. Вызов конструктора скрипта из библиотеки клиента ElasticSeach
3. Отправка запроса к ElasticSearch
Имплементация скрипта.
Думаю, здесь все просто. Сначала приоритет для строки равен нулю. В зависимости от условий он может подняться до 4-х
Я использовал пакет "gopkg.in/olivere/elastic.v6", который любезно предоставил конструктор для скрипта сортировки. Также есть возможность передать несколько параметров(
Params
). В конце нужно не забыть указать порядок сортировки по убыванию приоритетаOrder(false)
Делаем стандартную для этой библиотеки отправку запроса, вызвав
Do(ctx)
.
Наш скрипт помещается в методSortBy(builder)
. Также внутри уже приоритезированных строк мы можем применить дополнительную сортировку, например по id записиSort("Id", true)
Ну вот и все, пожалуй. Успехов в поиске данных!