В OpenSearch агрегация - это сбор или объединение связанных вещей. Фреймворк агрегации собирает данные на основе документов, соответствующих поисковому запросу, что помогает создавать сводки данных.
С помощью агрегаций вы можете не только искать данные, но и делать шаг вперед, извлекая аналитическую информацию, что облегчает организациям извлечение информации из накопленных данных.
Агрегации используются в Kibana повсеместно: в дашбордах, приложении APM, приложении Machine Learning и так далее.
OpenSearch организует агрегации в виде:
- Агрегация метрик - вычисление метрик на основе значений полей, например суммы или среднего значения.
- Агрегация по ведрам - документы группируются в ведра, также известные как бины, с помощью агрегации по ведрам на основе значений полей, диапазонов или других факторов.
- Конвейерные агрегации - принимают данные из других агрегаций, а не из полей или документов.
В отличие от агрегации метрик, агрегация ведер создает ведра документов, а не вычисляет метрики по полям. В зависимости от типа агрегации, каждый бакет имеет критерий, который решает, "попадает" ли в него документ в текущем контексте. Наборы документов фактически определяются ведрами. Агрегаторы ведер возвращают и вычисляют количество документов, которые "попали" в каждое ведро, в дополнение к самим ведрам.
В отличие от агрегации метрик, агрегации ведер способны содержать подагрегации. Для ведер, созданных "родительским" агрегатором ведер, эти подагрегации будут агрегированы. Существуют различные агрегаторы ведер, каждый из которых имеет свой уникальный подход к "агрегации". Одни определяют один бакет, другие - заданное количество нескольких бакет, третьи определяют бакеты динамически, по мере сбора данных.
Композитная агрегация определяется в разделе агрегации ведер. Составные агрегации - это многоведерные агрегации, которые объединяют в корзины из многих источников для получения составных корзин.
Как реализовать составные агрегации в OpenSearch
Основным необходимым параметром для составной агрегации является параметр sources. При определении источников вы должны дать им отличительное имя. При создании составных ведер параметр sources указывает поля источника, которые необходимо использовать. Порядок возврата ключей зависит от порядка определения источников. В параметре sources можно использовать любой из следующих типов, включая terms, histogram, date histogram и GeoTile grid.
Когда в качестве источника значений используются термины, процесс напоминает агрегацию терминов. В полном соответствии с агрегацией терминов значения берутся из поля. Можно использовать поле времени выполнения для генерации значений для составных ведер, как и в случае с агрегацией терминов. Ниже приведен пример составной агрегации, которая была выполнена для индекса authors с использованием terms в качестве источника в параметре sources, и этот источник агрегирует поле "author_name".
1 2 3 4 5 6 7 8 9 10 11 12 13 | GET authors/_search { "size": 0, "aggs": { "our_buckets": { "composite": { "sources": [ { "authors": { "terms": { "field": "author_name" } } } ] } } } } |
Источник значений гистограммы можно использовать для создания интервалов фиксированного размера над числовыми данными. Преобразование числовых значений задается параметром interval. Например, если интервал задан равным 5, число 106 будет преобразовано в 105, что является ключом для интервала между 105 и 110. Можно использовать поле времени выполнения для генерации значений для составных ведер, как и при агрегации гистограмм.
Ниже приведен пример составной агрегации, выполненной для индекса авторов с использованием гистограммы в качестве источника в параметре sources с интервалом, установленным на 5, и этот источник имеет имя "booksnum", и он использует поле books_number, которое представляет количество опубликованных книг для авторов.
1 2 3 4 5 6 7 8 9 10 11 12 13 | GET authors/_search { "size": 0, "aggs": { "our_buckets": { "composite": { "sources": [ { "booksnum": { "histogram": { "field": "books_number", "interval": 5 } } } ] } } } } |
date_histogram и источник значений histogram похожи. За исключением интервала. Интервал определяется выражением даты/времени в date_histogram, в отличие от источника значений гистограммы.
Ниже приведен пример составной агрегации, выполненной для индекса books с использованием date_histogram в качестве источника в параметре sources с интервалом, установленным на одну неделю. Источник имеет имя "week" и использует поле publish_date.
Поле publish_date представляет собой дату публикации книги, что создает интервал в неделю и переводит все значения publish_date в начало ближайшего интервала.
1 2 3 4 5 6 7 8 9 10 11 12 13 | GET books/_search { "size": 0, "aggs": { "our_buckets": { "composite": { "sources": [ { "week": { "date_histogram": { "field": "publish_date", "calendar_interval": "1w" } } } ] } } } } |
Для выражения интервала в date_histogram можно использовать следующие термины: секунда, минута, час, день, неделя, месяц, квартал и год. Парсер единиц времени поддерживает использование аббревиатур для указания значений времени. Обратите внимание, что нет поддержки дробных значений времени, но это можно обойти, переключившись на другую единицу времени (например, 2,5 часа можно указать как 150 метров).
Дата_гистограммы имеет три параметра: формат, временная_зона и смещение. Дата внутренне хранится как 64-битное значение с временной меткой в миллисекундах с момента начала. В качестве ключей bucket возвращаются эти временные метки. Вместо этого вы можете использовать формат, указанный параметром format, чтобы вернуть отформатированную строку даты. Ниже приведен пример использования параметра format в источнике date_histogram.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | GET books/_search { "size": 0, "aggs": { "our_buckets": { "composite": { "sources": [ { "formatteddate": { "date_histogram": { "field": "publish_date", "calendar_interval": "1d", "format": "MM-dd-yyyy" } } } ] } } } } |
OpenSearch хранит время и дату в формате UTC. По умолчанию UTC также используется для всех вычислений и округлений. Чтобы указать, что в букинге должен использоваться другой часовой пояс, используйте параметр time_zone.
Чтобы изменить начальное значение каждого ведра на заданную положительную (+) или отрицательную (-) длительность смещения, например 1h для часа или 1d для дня, используйте параметр offset. Например, при использовании интервала дня каждый бакет работает с полуночи до полуночи. Теперь каждый бакет работает с 7 утра до 7 утра, если параметр смещения установлен на +7h. После изменения временной_зоны вычисляется начальное смещение каждого ведра.
При работе с полями геоточек источник значений geotile_grid делит точки на ведра, соответствующие ячейкам сетки. Только ячейки с совпадающими данными включаются в результирующую сетку, которая может быть разреженной по своей природе. Каждая ячейка представляет собой плитку карты, подобно тому, как это делается на многих сайтах онлайн-карты. Каждая ячейка идентифицируется с помощью формата "{zoom}/{x}/{y}", где zoom равен точности, которую задает пользователь.
Ниже приведен пример составной агрегации, выполненной для индекса авторов с использованием geotile_grid в качестве источника в параметре sources с точностью, установленной на 6, и этот источник имеет имя "authorsloc" и использует поле authors_location, которое представляет местоположение автора.
1 2 3 4 5 6 7 8 9 10 11 12 13 | GET authors/_search { "size": 0, "aggs": { "our_buckets": { "composite": { "sources": [ { "authorsloc": { "geotile_grid": { "field": "authors_location", "precision": 6 } } } ] } } } } |
Для изготовления ячеек размером менее 10 см на 10 см используется высокоточный геотекстиль длиной 29. Поскольку каждую плитку не нужно производить и загружать в память, такая точность подходит именно для составных агрегатов. Количество используемых плиток можно уменьшить, ограничив источник георешетки определенным геограничным полем. Когда только небольшая часть географической области требует высокой точности тайлов, такие ограничения очень полезны.
В параметре sources можно использовать массив источников значений. Для создания составных ведер можно комбинировать различные источники значений. Как показано в примере ниже, из значений, полученных из двух источников значений, гистограммы дат и терминов, будут сгенерированы составные ведра. Два значения, по одному для каждого источника значения, указанного в агрегации, составляют каждое ведро. Возможна любая комбинация, при этом составные ведра сохраняют порядок массива.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | GET books/_search { "size": 0, "aggs": { "our_buckets": { "composite": { "sources": [ { "week": { "date_histogram": { "field": "publish_date", "calendar_interval": "1w" } } }, { "authors": { "terms": { "field": "author_name" } } } ] } } } } |
Составные ведра обычно располагаются в соответствии с их естественным расположением. Значения располагаются в порядке возрастания. Если требуется много источников значений, упорядочивание выполняется для каждого источника значений. Первое значение составного ведра сравнивается с первым значением другого составного ведра, и если они равны, то следующие значения в составном ведре используются для разрыва связей. Если в определении источника значений явно задать порядок asc (значение по умолчанию) или desc (порядок убывания), то можно указать направление сортировки для каждого источника значений. Как показано в примере ниже, составное ведро будет отсортировано по возрастанию, если сравниваются значения из источника terms, и по убыванию, если сравниваются значения из источника date_histogram.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | GET books/_search { "size": 0, "aggs": { "our_buckets": { "composite": { "sources": [ { "week": { "date_histogram": { "field": "publish_date", "calendar_interval": "1w", "order": "desc" } } }, { "authors": { "terms": { "field": "author_name", "order": "asc" } } } ] } } } } |
Документы, не имеющие значения для указанного источника, по умолчанию игнорируются. Установив для параметра missing_bucket значение true, вы можете включить их в ответ, зная, что значение параметра missing_bucket равно false.
С помощью необязательного параметра missing_order можно определить, где будет отображаться нулевой бакет. Нулевой бакет располагается в первой или последней позиции, в зависимости от того, является ли параметр missing_order первым или последним. Расположение ведра определяется порядком источника, если параметр missing_order отсутствует или установлен по умолчанию. Ведро находится на первом месте, если порядок является возрастающим (asc). Ведро находится на последнем месте, если порядок является нисходящим (descending).
Количество возвращаемых составных ведер можно задать с помощью параметра size. Если задать параметр size равным 10, то будут возвращены первые 10 составных ведер, сгенерированных из источников значений, поскольку каждое составное ведро рассматривается как одно ведро. Массив, содержащий значения, экстраполированные из каждого источника значений, включается в ответ вместе со значениями для каждого составного ведра. Значение параметра size по умолчанию равно 10.
Если количество составных ведер слишком велико (или не определено), чтобы вернуть их в одном ответе, можно разделить поиск на несколько запросов. Запрашиваемый размер - это именно то количество составных ведер, которое будет возвращено в ответе, так как составные ведра по своей природе плоские (если предположить, что возвращается не менее размера составных ведер). Рекомендуется использовать небольшой размер (например, 100 или 1000), а затем параметр after, чтобы получить следующие результаты, если необходимо получить все составные ведра.
Составная агрегация может содержать подагрегаты, как и любая агрегация ведер. Другие ведра или статистика по каждому составному ведру, полученному с помощью этого родительского агрегата, могут быть вычислены с помощью этих подагрегатов.
Последствия
Стоимость составного агрегата высока. Перед развертыванием составного агрегата в производстве проведите нагрузочное тестирование приложения.
Примечания и полезные сведения
- OpenSearch кэширует результаты часто используемых агрегаций в кэше запросов шарда для более быстрого ответа. Используйте одну и ту же строку предпочтений для каждого поиска, чтобы получать кэшированные результаты. Одна и та же строка предпочтений для поиска отправляется OpenSearch на одни и те же шарды. Шарды предоставляют кэшированные результаты агрегирования, если данные на них не меняются между поисками.
- Для достижения наилучшей производительности сортировка индекса должна быть установлена таким образом, чтобы она частично или полностью совпадала с порядком источников в составной агрегации.
- Для повышения эффективности раннего завершения рекомендуется установить в запросе значение track_total_hits равным false.
- Порядок источника имеет значение. Если ваш сценарий использования не требует порядка источников, вы можете следовать следующим простым правилам: поля с наибольшей кардинальностью должны располагаться первыми, убедитесь, что порядок полей соответствует порядку индекса