Блог Галс Софтвэр

Типы данных Elasticsearch

Elastic Stack
В Elasticsearch есть четыре категории типов данных, а именно основные типы данных, сложные типы данных, геоданные и специализированные типы данных, которые мы разберем в этой статье.

Основные типы данных

Первая категория, о которой поговорим — это основные типы данных.

Строки (Strings)

Хоть это и неожиданно, но строковые поля принимают строковые значения. Этот тип данных можно разделить на полнотекстовые поля и ключевые слова.

Строки — полнотекстовое поле (Full Text)

Полнотекстовые поля обычно используются для поиска релевантности на основе текста, например, при поиске продуктов по названию. Эти поля анализируются, что означает, что данные передаются через анализатор для преобразования строк в список отдельных выражений (токенов). Это происходит до того, как данные будут проиндексированы, и именно это позволяет Elasticsearch искать отдельные слова в полнотекстовом поле. Полнотекстовые поля не используются для сортировки и редко используются для агрегирования.

Строки — ключевые слова (Keyword)

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

Числовой (Numeric)

Этот тип данных используется для хранения числовых значений, таких как целые числа, числа с плавающей запятой и двойные числа, например. 1 и 1,5. Числовой тип данных поддерживает следующие числовые типы.

  • long (64-битное целое число со знаком)
  • целое число (32-битное целое число со знаком)
  • короткий (16-битное целое число со знаком)
  • байт (8-битное целое число со знаком)
  • double (64-битная с плавающей запятой двойной точности)
  • float (32-разрядная плавающая точка одинарной точности)

Даты

В Elasticsearch также есть тип данных «дата». Даты могут быть строкой, содержащей отформатированные даты (например, 2022-06-01 или 2022/06/01 15:00:00), целым числом, представляющим секунды с начала эпохи, или длинным числом, представляющим миллисекунды с начала эпохи. Последнее — это то, как Elasticsearch хранит даты внутри.

Даты – Форматы

При работе с датами можно выбирать их форматы. Формат по умолчанию определяется как дата с необязательным временем или количеством миллисекунд с начала эпохи. Это определяется следующим образом: strict_date_ optional_time||epoch_millis. Ниже приведены несколько примеров некоторых форматов по умолчанию, которые вы можете использовать при добавлении дат.

  • 01.06.2022 (только дата)
  • 2022-06-01T15:00:00Z (дата, включая время)
  • 1654095600000 (миллисекунд с начала эпохи)

Обратите внимание, что анализатор даты по умолчанию поддерживает форматы, определенные стандартом ISO, поэтому эти примеры — не единственные форматы, которые можно использовать. Если вы определяете собственный формат даты, вы можете использовать различные постоянные значения, предоставляемые Elasticsearch, которые действуют как заполнители при определении формата. Обратите внимание, что вы можете использовать логическое ИЛИ, как в языке программирования, разделив два заполнителя двумя вертикальными чертами (||).

Логический

Если поле может содержать только значения on или off, подходит логический тип данных. Как и в JSON, логические поля могут принимать значения true и false. Они также принимают строки и числа, которые будут интерпретироваться как логические значения. False значения включают логическое значение false, строку со значением «false», «off», «no», «0» или пустую строку («») или число 0. Все, что не интерпретируется как false, будет интерпретироваться как истинное.

Бинарный

Также возможно хранить двоичные данные в поле. Эти данные будут храниться в виде строки в кодировке Base64 и не будут доступны для поиска. Примером может служить строка aHR0cDovL2NvZGluZ2V4cGxhaW5lZC5jb20=.

Комплексные типы данных

Объект

Документы JSON являются иерархическими, что означает, что объект может содержать внутренние объекты. В Elasticsearch они выравниваются перед индексацией и хранятся в виде простых пар ключ/значение. Рассмотрим пример:

{
     "message": "Какой-то текст",
     "client.age": 26,
     "customer.address.city": "Москва",
     "customer.address.country": "Россия"
}

Если клиент — это объект, имеющий свойство age, то это свойство будет храниться в поле с именем client.age. То же самое относится и к вложенным объектам, как в примере с адресом.

Массив

Иногда может понадобиться сохранить массив значений. Elasticsearch, к сожалению, не имеет такого типа данных. Это связано с тем, что любое поле может содержать ни одного, одно или более значений по умолчанию, без явного определения. Это означает, что, просто передав массив значений в поле, Elasticsearch автоматически сохранит эти значения, даже для поля, которое, например, было отображено как строка. Однако, все значения в массиве должны относиться к одному и тому же типу данных. Если явное сопоставление не определяет тип данных, то Elasticsearch выведет его на основе первого значения в массиве.

Ниже приведены несколько примеров добавления массивов в поле Elasticsearch.

Массив строк: ["Elasticsearch", "super"]
Массив целых чисел: [1, 2]
Массив c массивами: [1, [2, 3]] — эквивалент [1, 2, 3]
Массив объектов: [{ "name": "Гена", "age": 26 }, { "name": "Вася", "age": 32 }]

Помимо простых типов данных, в массив также можно добавлять сложные типы данных, например объекты.

Массивы — Объекты

Elasticsearch сводит иерархию объектов к парам ключ/значение, потому что в Lucene нет понятия внутренних объектов, как в JSON. Это означает, что нельзя запросить каждый объект независимо от других объектов в массиве. Рассмотрим приведенный ниже пример:

{ "users: [{ "name": "Гена", "age": 26}, { "name": "Вася", "age": 32 }] }

Этот массив объектов хранится так:

{ "users.name": ["Гена", "Вася"], "users.age": [32, 26] }

Массив содержит два пользовательских объекта со свойствами name и age. Когда этот массив хранится в Lucene, все значения свойства в объектах добавляются в виде массива в одно поле — в данном случае поля с именами users.name и users.age. При этом связи между свойствами теряются. В этом конкретном примере связь между именем Гена и возрастом 26 лет теряется, поскольку значения не отсортированы. Следствием этого является то, что поиск пользователя по имени Гена, которому 26 лет, даст неверные результаты. Хорошей новостью является то, что есть решение этой проблемы, на случай, если вам понадобится выполнить такой поиск.

Вложенный

Решением упомянутой выше проблемы является вложенный тип данных. Используйте этот тип данных, когда вам нужно индексировать массивы объектов и поддерживать независимость каждого объекта. В этом случае значения для всех объектов не будут смешиваться, как в примере выше. Внутри каждый объект в массиве индексируется как отдельный скрытый документ. В результате вы можете запрашивать определенные объекты на основе значений их полей, используя специальный запрос с указанием на вложенность. Внутри Elasticsearch, вложенные объекты запрашиваются, как если бы они были проиндексированы в виде отдельных документов. Технически это так, но об этом можно не задумываться.

Геоданные

Геоточка

Тип данных геоточка используется для хранения пар широта-долгота и может использоваться для поиска документов в радиусе некоторых координат, сортировки по расстоянию от некоторых координат и т. д. Значения для поля геоточка могут быть добавлены в четыре разных формата. Первый — как объект со свойствами широты и долготы:

{
     "location": {
          "lat": 55.755394,
          "lon": 37.635131
     }
}

Второй — в виде строки с широтой и долготой, разделенными запятой, и именно в таком порядке:

{
     "location": "55.755394, 37.635131"
}

Третий — это геохеш:

{
     "location": "ac43fgrt4f67"
}

И четвёртый — массив:

{
    "location": [37.635131, 55.755394]
}

Обратите внимание, что по сравнению с другими форматами широта и долгота поменялись местами. Причина этого в том, чтобы соответствовать GeoJSON.

Геофигура

Поле геофигуры может содержать прямоугольники и многоугольники, поэтому может использоваться для создания сложных фигур. Этот тип данных нужно использовать, когда геоточки недостаточно.

Геофигуру можно построить разными способами, некоторые из которых представляют из себя линии или полигон. Linestring — это массив из двух или более позиций, который является массивом из массивов. Если массив содержит только две позиции, результатом будет прямая линия. Многоугольник также добавляется в виде массива массивов, где каждый массив содержит точки. Первая и последняя точки во внешнем массиве должны совпадать, что замыкает полигон.

Специализированные типы данных

IPv4

Первый — это тип данных IPv4. Неудивительно, что он используется для сопоставления адресов IPv4. Elasticsearch сохраняет значения для поля IPv4 как длинные значения внутри.

Автозаполнение

Этот тип данных используется для автозаполнения (completion). Это т.н. префиксный подсказчик, и, хотя он не исправляет орфографию, он полезен для предоставления пользователю подсказок во время поиска, например, в Google. Это делается путем сохранения преобразователя с конечным состоянием как части индекса, что обеспечивает очень быструю загрузку и выполнение.

Количество токенов

Тип данных token_count представляет собой целочисленное поле, которое принимает строковые значения. Происходит следующее: анализируются строковые значения и индексируется количество токенов в строках. Примером использования может быть то, что свойство имени имеет поле длины типа token_count. Затем может быть выполнен поисковый запрос, чтобы найти людей, чье имя содержит заданное количество токенов, например, разделенных пробелом.

Вложение

Существует также тип данных вложения, который позволяет Elasticsearch индексировать вложения для многих распространенных форматов, таких как файлы PDF, электронные таблицы, презентации PowerPoint и многое другое. Вложения хранятся в виде строки в кодировке Base64. Эта функция доступна в виде плагина, который необходимо установить на все узлы. Это легко сделать, введя приведенную ниже команду, предполагая, что узел работает в среде UNIX.

sudo /path/to/elasticsearchbin/plugin install mapper-attachments

Если вы установите этот плагин, обратите внимание, что вы должны перезапустить каждую ноду после завершения установки.

Это был пошаговый обзор основных типов данных в Elasticsearch, которые вам, скорее всего, понадобятся или с которыми вы столкнетесь. Спасибо за внимание!

Если вы только начинаете изучение Elastic, приходите на наш 3-дневный семинар инструктаж и освойте весь функционал в сжатый срок.

Если нужна консультация по Elastic или у вас другой вопрос, оставьте заявку в форме обратной связи.