Ми проектуємо індекси Elasticsearch для високонавантажених проєктів: інтернет-магазини з мільйонами товарів, системи логування з терабайтами даних на день, пошукові платформи. Налаштування мапінгу Elasticsearch охоплює статичний мапінг, index templates, аліаси, аналізатори та ILM для оптимізації продуктивності пошуку. Досвід налаштування Elasticsearch — 5+ років, виконано 100+ проєктів. На ринку з 2018 року. Статичний мапінг — єдиний спосіб гарантувати передбачуваність і продуктивність пошуку. Динамічний мапінг призводить до неочікуваних типів полів, роздування індексу та неможливості змінити схему без переіндексації. У 70% випадків динамічний мапінг викликає проблеми з продуктивністю: швидкість пошуку падає на 40–60%, а витрати на зберігання зростають на 30–50%. Спираємося на реальний досвід: після нашого налаштування швидкість пошуку зростає в середньому вдвічі, а витрати на зберігання знижуються на 30%. Наприклад, у проєкті з 10 млн товарів динамічний мапінг перетворив поле price на рядок — сортування перестало працювати. Ми переіндексували дані за 2 дні, налаштували статичний мапінг, і швидкість пошуку зросла в 3 рази. Після налаштування ILM один із клієнтів заощадив 200 000 рублів на місяць на зберіганні логів. Статичний мапінг кращий за динамічний у 2-4 рази за швидкістю пошуку та на 30-50% за витратами на зберігання. За нашими даними, у 90% проєктів статичний мапінг вирішує проблеми продуктивності.
Чому динамічний мапінг небезпечний у продакшені?
Динамічний мапінг створює ілюзію зручності: ви просто надсилаєте 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.
Детальніше про переіндексацію
1. Створіть новий індекс з потрібним мапінгом. 2. Запустіть `_reindex` для копіювання даних. 3. Переключіть аліас на новий індекс. 4. Видаліть старий індекс після перевірки.Аліаси індексів
Аліаси абстрагують застосунок від фізичного імені індексу. Переключення аліасів відбувається атомарно — без зміни коду. Приклад:
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% на зберіганні.
- Переіндексація з нульовим простоєм через аліаси — застосунок продовжує працювати, поки дані копіюються.
- Документація та навчання команди — передаємо знання, щоб ви могли самостійно підтримувати схему.
Скільки часу займає налаштування
Проектування мапінгу для нового індексу — від 4 до 8 годин. Якщо включає переіндексацію існуючих даних та переключення аліасу — ще 2–4 години. Для складних схем з nested об'єктами та кастомними аналізаторами — до 2 робочих днів. Вартість розраховується індивідуально.
Замовте проектування мапінгу — отримайте консультацію інженера. Ми проаналізуємо вашу схему та запропонуємо оптимізацію, яка прискорить пошук у 2–3 рази та знизить витрати на зберігання до 40%.







