Мы проектируем индексы Elasticsearch для высоконагруженных проектов: интернет-магазины с миллионами товаров, системы логирования с терабайтами данных в день, поисковые платформы. Опыт настройки Elasticsearch — более 5 лет, выполнено 100+ проектов. Статический маппинг — единственный способ гарантировать предсказуемость и производительность поиска. Динамический маппинг приводит к неожиданным типам полей, раздуванию индекса и невозможности изменить схему без переиндексации. В 70% случаев динамический маппинг вызывает проблемы с производительностью: скорость поиска падает на 40–60%, а затраты на хранение растут на 30–50%. Опираемся на реальный опыт: после нашей настройки скорость поиска вырастает в среднем вдвое, а затраты на хранение снижаются на 30%. Например, в проекте с 10 млн товаров динамический маппинг превратил поле price в строку — сортировка перестала работать. Мы переиндексировали данные за 2 дня, настроили статический маппинг, и скорость поиска выросла в 3 раза. После настройки ILM один из клиентов сэкономил 200 000 рублей в месяц на хранении логов.
Почему динамический маппинг опасен в продакшене?
Динамический маппинг создаёт иллюзию удобства: вы просто отправляете JSON, а Elasticsearch сам определяет типы. На практике это приводит к неожиданным результатам: строки могут стать text или keyword в зависимости от значения, числа — float вместо integer, а массивы объектов — object вместо nested. В результате поиск по связанным полям массива даёт некорректные результаты. Исправить это можно только переиндексацией, которая требует времени и ресурсов. Dynamic: strict полностью исключает эти проблемы.
Сравнение статического и динамического маппинга
| Параметр | Статический маппинг | Динамический маппинг |
|---|---|---|
| Производительность поиска | Высокая (стабильная) | Падает на 40–60% при росте данных |
| Контроль схемы | Полный, ошибка при неописанных полях | Случайные типы, раздувание индекса |
| Затраты на хранение | На 30–50% ниже | Выше из-за избыточных полей |
| Время на переиндексацию | Зависит от размера (часы) | Требуется при изменении типа поля |
| Подходит для | Продакшен, highload | Прототипы, dev-среды |
Типы полей Elasticsearch: выбор под задачу
| Тип поля | Назначение | Когда использовать | Влияние на размер | Влияние на скорость индексации |
|---|---|---|---|---|
text |
Полнотекстовый поиск | Для заголовков, описаний, контента | Высокий (хранение позиций) | Средняя |
keyword |
Точное совпадение, фильтры | Для ID, статусов, тегов, категорий | Низкий (не анализируется) | Высокая |
integer/long |
Числовые значения | Для цен, количества, возраста | Низкий | Высокая |
date |
Дата/время | Для дат создания, обновления | Низкий | Высокая |
boolean |
Флаги | Для is_active, is_deleted |
Очень низкий | Высокая |
object |
Вложенный объект | Для структурированных данных одного объекта | Средний | Средняя |
nested |
Массив объектов | Для товаров с вариантами, где нужен точный поиск внутри массива | Высокий (доп. структура) | Низкая |
geo_point |
Геокоординаты | Для точек на карте, гео-поиска | Низкий | Высокая |
dense_vector |
Векторное представление | Для семантического поиска, рекомендаций | Высокий (размерность) | Низкая |
Как выбрать тип поля для ваших данных
Для полнотекстового поиска используйте text с keyword sub-field для сортировки. Для точного совпадения — keyword. Числовые диапазоны — integer или long. Даты — date. Если у вас массив объектов и нужна корректная фильтрация по связанным полям, выбирайте nested. Иначе достаточно object. Для геоданных — geo_point. Векторный поиск требует dense_vector. В 95% проектов правильный выбор типа поля сразу снижает размер индекса на 20–30%.
Создание индекса с явным маппингом: пошаговое руководство
- Определите поля и их семантику, учитывая, какие данные будут храниться и какие поля необходимы для поиска, фильтрации, сортировки.
- Выберите типы из таблицы выше. Учтите, что
textанализируется,keyword— нет. - Настройте анализаторы для
text-полей. Например, для русского текста используйтеsnowballсstop-фильтром. - Установите
dynamic: strict. Это защитит от случайных изменений схемы. - Создайте индекс через PUT-запрос с маппингом. Пример ниже.
PUT /products { "settings": { "number_of_shards": 3, "number_of_replicas": 1, "analysis": { "analyzer": { "product_search": { "type": "custom", "tokenizer": "standard", "filter": ["lowercase", "stop", "snowball"] } } } }, "mappings": { "dynamic": "strict", "_source": { "enabled": true }, "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "product_search", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "description": { "type": "text", "analyzer": "product_search", "index_options": "positions" }, "category": { "type": "keyword" }, "tags": { "type": "keyword" }, "price": { "type": "scaled_float", "scaling_factor": 100 }, "stock": { "type": "integer" }, "is_active": { "type": "boolean" }, "created_at": { "type": "date", "format": "strict_date_optional_time||epoch_millis" }, "attributes": { "type": "nested", "properties": { "name": { "type": "keyword" }, "value": { "type": "keyword" } } }, "location": { "type": "geo_point" } } } } "dynamic": "strict" запрещает добавление неописанных полей. Документ с неизвестным полем вызовет ошибку маппинга. Альтернативы: "true" (добавляет автоматически), "false" (игнорирует неизвестные поля, не индексирует). Обслуживание статического маппинга обходится в 2 раза дешевле динамического из-за снижения затрат на хранение и скорость поиска.
Index Templates для автоматизации
Index templates автоматически применяют маппинг к новым индексам по шаблону. Это незаменимо при работе с data streams и rolling-индексами, например для логов.
PUT _index_template/logs-template { "index_patterns": ["logs-*"], "priority": 100, "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 1, "index.lifecycle.name": "logs-policy", "index.lifecycle.rollover_alias": "logs" }, "mappings": { "dynamic": "false", "properties": { "@timestamp": { "type": "date" }, "level": { "type": "keyword" }, "service": { "type": "keyword" }, "message": { "type": "text" }, "trace_id": { "type": "keyword" }, "duration_ms": { "type": "integer" } } } }, "data_stream": {} } Как изменить маппинг существующего индекса
Большинство изменений маппинга невозможны без переиндексации. Можно только добавлять новые поля или расширять параметры (ignore_above, добавление fields). Нельзя изменить тип существующего поля. Для добавления поля:
PUT /products/_mapping { "properties": { "brand": { "type": "keyword" } } } Для изменения типа — создайте новый индекс, запустите _reindex и переключите алиас. Полный процесс переиндексации описан в Reindex API.
Алиасы индексов
Алиасы абстрагируют приложение от физического имени индекса. Переключение алиасов происходит атомарно — без изменения кода. Пример:
POST _aliases { "actions": [ { "add": { "index": "products_v2", "alias": "products", "is_write_index": true } }, { "remove": { "index": "products_v1", "alias": "products" } } ] } _source и оптимизация хранения
_source хранит исходный JSON документа. Отключение экономит место, но теряется возможность использовать update, reindex и highlight без оригинала. В большинстве случаев отключать не нужно. Для экономии можно исключить тяжёлые поля из _source через _source.excludes.
Что входит в работу по настройке индексов
- Аудит текущей схемы и запросов — выявляем узкие места, например, N+1 запросы или неоптимальные типы полей.
- Проектирование маппинга с учётом бизнес-логики — выбираем типы, анализаторы, задаём
dynamic: strict. - Настройка анализаторов под язык и задачи — для русского текста используем
snowballсstop-фильтром, для английского —english. - Создание index templates и политик жизненного цикла (ILM) — автоматизируем управление индексами, экономим до 40% на хранении.
- Переиндексация с нулевым downtime через алиасы — приложение продолжает работать, пока данные копируются.
- Документация и обучение команды — передаём знания, чтобы вы могли самостоятельно поддерживать схему.
Сколько времени занимает настройка
Проектирование маппинга для нового индекса — от 4 до 8 часов. Если включает переиндексацию существующих данных и переключение алиаса — ещё 2–4 часа. Для сложных схем с nested объектами и кастомными анализаторами — до 2 рабочих дней. Стоимость рассчитывается индивидуально.
Закажите проектирование маппинга — получите консультацию инженера. Мы проанализируем вашу схему и предложим оптимизацию, которая ускорит поиск в 2–3 раза и снизит затраты на хранение до 40%.







