Налаштування індексів та мапінгів Elasticsearch

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Налаштування індексів та мапінгів Elasticsearch
Середній
~2-3 дні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1360
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    957
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    948

Ми проектуємо індекси 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%.

Створення індексу з явним мапінгом: покрокове керівництво

  1. Визначте поля та їх семантику, враховуючи, які дані будуть зберігатися та які поля необхідні для пошуку, фільтрації, сортування.
  2. Виберіть типи з таблиці вище. Врахуйте, що text аналізується, keyword — ні.
  3. Налаштуйте аналізатори для text-полів. Наприклад, для російського тексту використовуйте snowball з stop-фільтром.
  4. Встановіть dynamic: strict. Це захистить від випадкових змін схеми.
  5. Створіть індекс через 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%.

Послуги бекенд-розробки: production-grade надійність

На production-сервері о 3:14 ночі черга Laravel Jobs перестала оброблятися — 40 000 необроблених завдань у Redis. Причина: worker упав через memory leak у статичній змінній Eloquent observer, supervisor не перезапустив через misconfigured stopwaitsecs. Ми розбирали такий інцидент на проекті з 500 RPS: діагностика 4 години, фікс — 20 хвилин. Щоб ви не втрачали гроші, пропонуємо послуги бекенд-розробки з акцентом на production-grade надійність — 10+ років досвіду, 50+ проектів, 5 років на ринку. Оцінимо ваш проект за 2 дні.

Які проблеми вирішуємо

N+1 запити: головний вбивця швидкості

N+1 — найпоширеніша причина повільних сторінок у Laravel-додатках. Стандартна історія: сторінка працювала нормально на dev з 10 записами, на production з 10 000 — 8-секундне завантаження.

Laravel Debugbar у dev-оточенні показує кількість запитів. Більше 20 — сигнал для audit.

Model::preventLazyLoading(! app()->isProduction());

Telescope для профілювання: логує всі запити, jobs, mail, notifications з деталізацією. Після впровадження eager loading час завантаження сторінки падає з 8 с до 0.3 с — у 27 разів.

Memory leak у статичних змінних

У Laravel Octane або Swoole додаток тримається в пам’яті між запитами. Статичні змінні не скидаються — призводять до неконтрольованого росту пам’яті. Використовуємо defer-функції та контейнерні біндинги для коректного скидання стану.

Неправильний connection pool

Rails, Laravel, Django відкривають нове з'єднання PostgreSQL на кожен PHP/Python процес. 100 воркерів — 100 з'єднань. PostgreSQL деградує від 200+ активних з'єднань через overhead на управління.

PgBouncer у transaction pooling: 1000 воркерів → 20–50 реальних з'єднань. Це знижує latency на 40% та зменшує витрати на хостинг на 30% — при середній вартості хостингу $2,000/міс економить $600/міс. GIN-індекс для JSONB до 100 разів швидший за B-tree при пошуку.

Як Octane справляється з високим навантаженням?

Laravel Octane (RoadRunner або Swoole) прибирає overhead bootstrap на кожен HTTP-запит. Приріст: 3–8x на синтетичних бенчмарках, 2–4x на реальних додатках. Важливо: не зберігати стан у статичних змінних — застосовуємо це на проектах >1000 RPS.

Як PostgreSQL допомагає уникнути повільних запитів?

Використовуємо composite indexes для WHERE + ORDER BY, partial indexes для фільтрів з високою селективністю, GIN-індекси для JSONB та full-text search. to_tsvector + GIN замість LIKE '%query%' — запобігає seq scan навіть на мільйонах записів. Аналізуємо плани через EXPLAIN ANALYZE та pg_stat_statements.

Як обрати стек для вашого проекту?

Стек Коли використовувати
Laravel + Octane CRUD, бізнес-логіка, REST/GraphQL API, адмінки
Node.js (Fastify) Realtime WebSocket, streaming, serverless, висока I/O concurrency
Go Високонавантажені мікросервіси (>10k RPS), gRPC, DevOps-інструменти
Django + DRF ML-пайплайни, інтеграція з AI, складна обробка даних
Ruby on Rails Швидкий MVP з багатим екосистемою гемів

Node.js виправданий для realtime: Laravel публікує події в Redis Pub/Sub, Node.js підписується та транслює клієнтам. Go — для goroutines (10k з'єднань на сервер — норма), але розробка повільніша, ніж Laravel.

Чому Redis критичний для продуктивності?

Redis виконує кілька ролей:

Роль Деталі
Кеш Кешування результатів важких запитів, фрагментів HTML
Черги Backend для Laravel Queue / Celery
Session store Distributed sessions в multi-instance оточенні
Pub/Sub Realtime події між сервісами
Rate limiting Sliding window counters для API throttling
Leaderboards Sorted Sets для рейтингів

Redis Cluster для горизонтального масштабування, Sentinel для автоматичного failover. Замовте консультацію щодо оптимізації Redis для вашого проекту.

Що входить в роботу під ключ

  • Архітектурне проектування (документація API, схема БД, діаграма сервісів)
  • Реалізація за узгодженим ТЗ з code review
  • Налаштування CI/CD (GitHub Actions, Docker), моніторингу (Sentry, Grafana), алертингу
  • Навантажувальне тестування (k6, wrk) зі звітом
  • Передача вихідних кодів, доступів, інструкція з деплою
  • Навчання команди замовника (2–3 сесії)
  • Гарантійна підтримка 1 місяць після здачі

Орієнтири по термінах

Задача Термін
REST API для мобільного/SPA (середня складність) 6–12 тижнів
Backend зі складною бізнес-логікою + інтеграції 12–20 тижнів
Високонавантажений сервіс на Go 8–16 тижнів
Міграція legacy PHP на Laravel 16–32 тижні

Вартість розраховується індивідуально після аналізу вимог до навантаження, інтеграцій та бізнес-логіки. Зв'яжіться з нами для безкоштовного аудиту вашого поточного backend — отримайте план оптимізації за 2 дні. Замовте консультацію та дізнайтеся, як знизити витрати на інфраструктуру на 30% без втрати продуктивності.