Какие типы данных (data types) поддерживаются в Elasticsearch для полей?

Ответ

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

1. Текстовые типы

  • text: Для полнотекстового поиска. Значение анализируется (разбивается на токены, применяются фильтры). Не используется для сортировки или точных агрегаций.
  • keyword: Для точного совпадения, фильтрации, сортировки, агрегаций. Значение не анализируется, хранится как есть. Критически важен для полей вроде status, tags, id.

2. Числовые типы

  • Целочисленные: byte, short, integer, long.
  • С плавающей точкой: half_float, float, double, scaled_float (удобен для цен, хранит long с заданным масштабом).
  • Почему выбор важен: Влияет на размер индекса и производительность. Использую минимально достаточный тип (например, integer вместо long).

3. Дата и время

  • date: Может принимать строки в множестве форматов (настраивается), числовые timestamp'ы в миллисекундах или секундах.
    "created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" }

4. Геопространственные типы

  • geo_point: Для широты/долготы (например, {"lat": 52.52, "lon": 13.40}). Позволяет искать точки в радиусе, сортировать по расстоянию.
  • geo_shape: Для сложных фигур (полигоны, линии). Используется для геозон.

5. Специальные типы

  • boolean: true/false.
  • binary: Для хранения Base64-кодированных бинарных данных (например, небольшие файлы). Не индексируется для поиска.
  • ip: Для IPv4/IPv6 адресов. Позволяет диапазонный поиск.
  • completion и search_as_you_type: Для реализации автодополнения (suggesters).

6. Типы для сложных объектов

  • object: Для вложенных JSON-объектов. Поля внутри индексируются «сплющенными».
  • nested: Для массивов объектов, где нужно сохранить независимость объектов. Требует специальных nested-запросов и агрегаций.
    "orders": {
      "type": "nested",
      "properties": {
        "product": { "type": "keyword" },
        "price": { "type": "float" }
      }
    }

7. Псевдо-типы

  • alias: Определяет псевдоним для существующего поля.

Пример маппинга для профиля пользователя:

PUT /users
{
  "mappings": {
    "properties": {
      "username": { "type": "keyword" },
      "bio": { "type": "text" },
      "age": { "type": "integer" },
      "registration_date": { "type": "date" },
      "last_login_ip": { "type": "ip" },
      "home_location": { "type": "geo_point" },
      "settings": {
        "type": "object",
        "properties": {
          "email_notifications": { "type": "boolean" }
        }
      }
    }
  }
}

Правильный выбор типа данных — это основа производительности и корректности поиска в Elasticsearch.

Ответ 18+ 🔞

А, ну это про типы данных в Elasticsearch, да? Ёпта, тема важная, как ни крути. Слушай, тут всё просто, но если накосячить с типами — потом будешь волосы на жопе рвать, когда поиск нихуя не работает или индекс жрёт памяти, как не в себя. Разберём по полочкам, без паники.

1. Текстовые — тут два главных кита

  • text: Это для нормального, человеческого поиска по словам. Туда пишешь "Привет, как дела?" — а внутри оно разбирает на кусочки, слова, убирает предлоги, приводит к одной форме. Для сортировки или точного совпадения — нихуя не годится, это важно.
  • keyword: А вот это — святое. Это для всяких статусов, тегов, айдишников. Хранится как есть, буква в букву. Хочешь фильтровать по status: "active", сортировать по имени или строить красивые графики-агрегации — только keyword. Запомни это, как "Отче наш". Если перепутаешь — будет тебе пизда рулю.

2. Числовые — не дури, бери по размеру Целые всякие: byte, short, integer, long. С дробями: half_float, float, double. Есть ещё scaled_float — хитрая жопа для цен, очень удобно. В чём прикол? А в том, чтобы не тыкать везде long, как полупидор. Если у тебя возраст пользователя, он в integer влезет — так и пиши. Сэкономишь место, и работать будет шустрее. Производительность, ёпта!

3. Дата и время (date) Тут можно ворочать даты как угодно. Кидай строку в человеческом формате, кидай таймстамп в миллисекундах — Elastic всё схавает, если правильно настроить.

"created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" }

Главное — format не забудь, а то сам от себя охуеешь, когда данные загрузятся, а поиск по дате не работает.

4. Гео-штуки — для карт и зон

  • geo_point: Широта/долгота, точка на карте. "Где наш курьер?" — вот это вот всё. Искать в радиусе, сортировать по ближайшему — красота.
  • geo_shape: Уже для понтов: полигоны, линии. Если нужно проверить, попадает ли адрес в зону доставки — твой выбор.

5. Специальные типы — для своих

  • boolean: Ну тут ясно, true или false. Включены уведомления или нет.
  • binary: Залить маленькую картинку или файлик в Base64. Но искать по нему — ни хуя себе, не индексируется оно.
  • ip: Для айпишников. Очень удобно, если нужно искать по диапазону "все адреса такой-то подсети".
  • completion и search_as_you_type: Это магия для автодополнения. Пользователь начал вводить "Моск" — а ему выпадает "Москва". Ёперный театр, как удобно!

6. Объекты и массивы — где можно обжечься

  • object: Просто вложенный JSON. Работает, но если у тебя там массив объектов — все свойства склеятся в одну кучу. Для простых штук сойдёт.
  • nested: А вот это — оружие массового поражения для сложных структур. Если у пользователя массив заказов, и каждый заказ — это объект с товаром и ценой, и ты хочешь искать внутри этих объектов... То без nested доверия ебать ноль. Только он сохраняет независимость объектов в массиве.
    "orders": {
      "type": "nested",
      "properties": {
        "product": { "type": "keyword" },
        "price": { "type": "float" }
      }
    }

    Запомни: для запросов к nested полям нужны специальные nested-запросы и агрегации. Иначе будешь удивление пиздец испытывать, когда результаты не сходятся.

7. Псевдо-тип (alias) Просто дать полю другое имя, чтобы не переписывать кучу запросов. Мелочь, а приятно.

Вот тебе живой пример, как это может выглядеть:

PUT /users
{
  "mappings": {
    "properties": {
      "username": { "type": "keyword" }, // Сортировать по имени — легко!
      "bio": { "type": "text" }, // Искать по словам в биографии
      "age": { "type": "integer" }, // Не `long`, экономим!
      "registration_date": { "type": "date" },
      "last_login_ip": { "type": "ip" }, // Смотри-ка, с какого IP заходил
      "home_location": { "type": "geo_point" }, // Где живёт, твою мать
      "settings": {
        "type": "object", // Простой вложенный объект
        "properties": {
          "email_notifications": { "type": "boolean" }
        }
      }
    }
  }
}

Короче, чувак, вся суть в том, чтобы думать головой, когда создаёшь маппинг. Выбрал не тот тип — потом терпения ноль ебать, переиндексируй всё заново. Лучше потратить время сразу, чем орать "какого хуя?!" потом.