Elasticsearch для мобільного застосунку: де ламається пошук
Пошук у застосунку рідко проєктують заздалегідь: зазвичай він виростає із запиту «знайти підрядок у назві» до основної бази. Поки в каталозі сотні позицій і один сервер, це працює непомітно.
Щойно асортимент зростає й користувачів стає більше, пошук перетворюється на вузьке місце, яке гальмує і каталог, і оформлення замовлення.
Перша точка відмови — релевантність видачі. Пошук за точним входженням не знаходить товар при друкарській помилці, іншому порядку слів або відмінку: «кросівки чоловічі» знаходиться, «чоловічі кросівки для бігу» — уже ні.
Elasticsearch закриває це розбором запиту на словоформи, словниками синонімів і нечітким зіставленням — але лише коли аналізатори, ваги полів і правила пріоритету налаштовані під конкретний каталог, а не залишені за замовчуванням.
Друга точка відмови — підказки й автодоповнення. Кожне натискання клавіші надсилає запит, і черга зростає швидше, ніж каталог. Повільний пошук тут видно одразу: користувач набирає слово, не отримує підказок і закриває застосунок.
Третя — навантаження на серверну частину. Пошукові запити конкурують за ті самі ресурси, що транзакції та оплата: важкі вибірки за підрядком забирають потужність у того, що має відповідати миттєво, і гальмує вже весь застосунок. Тому пошук виносять в окремий шар — розбираємо, де саме він ламається і як це закривається.
Ефект від переробки пошукового шару: швидкість і точність
До переробки пошук у застосунку виконувався запитами до основної бази: кожен уведений символ породжував вибірку з кількох таблиць із порівнянням за шаблоном.
На пікових навантаженнях такі запити конкурували з операціями оформлення замовлення, час відповіді видачі зростав до секунд, а частина звернень відпадала за часом очікування — користувач бачив порожній екран замість результатів.
Пошуковий шар винесли на Elasticsearch і побудували окремі індекси під товари, категорії та підказки. Індекси оновлюються за подіями зміни каталогу, повна перебудова йде у фоні й не блокує видачу.
Час відгуку скоротився на порядок і перестав залежати від обсягу каталогу: те, що раніше деградувало при зростанні асортименту, тепер тримається рівно.
Точність видачі зросла завдяки трьом механізмам.
Автодоповнення показує варіанти з перших уведених символів, виправлення друкарських помилок підхоплює запити з помилками в розкладці та пропущеними літерами, словник синонімів зводить різні формулювання одного товару до спільної видачі.
Частка релевантних результатів у першій десятці зросла з двох третин до майже повної — рахуємо її на розміченій вибірці реальних запитів, а не на тестових сценаріях.
Окремий ефект — зняте з основної бази навантаження. Пошукові запити більше до неї не доходять, тому пікові сплески обслуговуються без деградації оформлення замовлень.
Пішов цілий клас відмов: порожні видачі та обриви за часом очікування на розпродажах і в момент розсилок, які раніше закривали ручним масштабуванням.
Пошуковий шар поглинає сплеск сам, а при недоступності підказок видача продовжує працювати в усіченому режимі замість повної відмови.
Варіанти організації пошуку: Elasticsearch та альтернативи
Пошук у застосунку майже ніколи не будується на одній техніці: вибір залежить від обсягу каталогу, вимог до релевантності та того, наскільки застосунок терпимий до затримки відповіді. Нижче — чотири робочі варіанти, між якими реально обирають, та їхні обмеження.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Запити до основної бази | Каталог до кількох тисяч записів, пошук за назвою, немає вимог до друкарських помилок | Слабке ранжування результатів; кожен запит навантажує транзакційну базу |
| Окремий пошуковий сервіс (Elasticsearch) | Великий каталог, нечіткий пошук, морфологія, фасети, друкарські помилки | Потрібен свій контур: індексація, реплікація, моніторинг; дані живуть із затримкою від основної бази |
| Кеш підказок | Автодоповнення та частотні запити, де важлива миттєвість | Не замінює повноцінний пошук: покриває лише популярні запити, потребує прогрівання та скидання при оновленні даних |
| Гібридна схема | Каталог зростає, пошук уже став вузьким місцем | Складніша експлуатація: два сховища, синхронізація та правила, що вважати джерелом істини |
Схеми сумісні й допускають перехід: пошук ховається за єдиним інтерфейсом застосунку. Старт на запитах до бази, додавання кешу підказок і винесення в окремий пошуковий сервіс не потребують переписувати клієнт — змінюється лише реалізація за інтерфейсом.
Індексація йде асинхронно з основної бази, тому пошук залишається робочим, поки будується новий індекс.
Етапи впровадження: від аудиту запитів до передачі
Пошук у застосунку ламається частіше не в момент підключення движка, а на стику: фрази, які вводять люди, не збігаються з тим, як розмічені дані. Тому роботи йдемо послідовно, і кожен етап закінчується артефактом, який можна перевірити до переходу до наступного.
- Аудит запитів. Збираємо реальні пошукові фрази з логів і розмічаємо за сценаріями — каталог, автодоповнення, друкарські помилки та розкладка, повторні запити. На виході карта вузьких місць: де видача порожня, де релевантність провалюється, де користувач іде після першої сторінки.
- Схема індексів. Проєктуємо структуру під цю розмітку: які поля текстові, які фільтровані, де потрібні синоніми, морфологія та розбір друкарських помилок. Окремо вирішуємо, що зберігати в індексі, а що підтягувати з основної бази, щоб дані не розходилися.
- Налаштування видачі. Аналіз мови, ваги полів, правила ранжування за категоріями, посторінкова видача та підказки. Логіку релевантності описуємо й версіонуємо — Elasticsearch тут виконавець, а не джерело правил.
- Перевірка на трафіку. Нову видачу вмикаємо на частину реальних користувачів і порівнюємо з попередньою: частка запитів із переходом у картку, позиція цільового товару, час відповіді. Рішення про повне вмикання ухвалюємо за цифрами, а не за враженням.
- Спостережуваність. Налаштовуємо метрики та оповіщення: частка порожніх видач, помилки індексації, відставання оновлень. Це раннє попередження замість скарг користувачів.
- Передача підтримки. Віддаємо конфігурації в репозиторії, схеми, інструкцію з переіндексації та відкату, проводимо розбір із командою замовника. Готово, коли синоніми й правила змінюються без нас.
Конфігурації, схеми індексів і регламенти супроводу
Пошук, який ми налаштовуємо, передається разом із повним комплектом артефактів — не «чорною скринькою», а набором конфігурацій і правил, за якими систему можна розвивати й супроводжувати власними силами. Нижче — що саме залишається у вашої команди після здачі.
- Схеми індексів — мапінги полів і налаштування аналізаторів під морфологію, друкарські помилки та транслітерацію, з поясненням, чому поле зберігається саме так.
- Правила оновлення даних — що і з якою періодичністю потрапляє в індекс, як обробляються видалення й часткові збої, як проходить повна переіндексація без простою.
- Конфігурації середовищ — параметри контурів розробки, тестування та промислового з явно описаними відмінностями.
- Регламент супроводу — що робити при зростанні каталогу, зміні структури карток і плановому оновленні движка.
- Моніторинг пошуку — частка запитів без результатів, час відповіді, частка запитів із переходом до замовлення та пороги спрацювання оповіщень.
- Резервне копіювання та відкат — повні й інкрементальні копії індексів, порядок відновлення та час повернення пошуку в робочий стан.
- Документація — розгортання з нуля, карта типових відмов і точки, куди дивитися в першу чергу при деградації.
Кожен пункт перевіряється на прийманні: ми показуємо, як підняти контур з нуля за документацією та відтворити конфігурацію. Такий комплект означає, що пошук у застосунку можна розвивати й супроводжувати без нас — або разом із нами, коли обсяг робіт зростає.
Кейс: як пошук за каталогом прискорився після переробки
Каталог на кілька десятків тисяч позицій — той випадок, коли пошук перестає бути другорядною функцією.
У сервісі з широким асортиментом запити йшли напряму в основну базу: кожен уведений символ породжував важкий запит по всій таблиці товарів, підказки поверталися за 1,5–2 секунди, а потрібний товар потрапляв у першу п’ятірку лише в 38% запитів.
Причина була не лише у швидкості. Пошук не розумів друкарських помилок, словоформ, синонімів і латинської розкладки, піднімав зняті з продажу позиції вище за актуальні. Підтримка отримувала потік звернень «товар є, але пошук його не знаходить».
Що зробили
Ми винесли пошук в окремий індекс на Elasticsearch — основна база перестала бути вузьким місцем, а ранжування стало керованим. Налаштували аналізатори під російське та латинське введення: словоформи, синоніми, транслітерацію, стійкість до друкарських помилок і зайвих пробілів.
Додали бустинг за наявністю на складі, популярністю та новизною, щоб рідкісні й зняті позиції не піднімалися над ходовими.
Експлуатацію закрили окремо: індекс оновлюється інкрементально при зміні каталогу, без повного перезбирання, а при недоступності пошуку застосунок віддає кеш і штатні категорії замість порожнього екрана.
Метрики до і після
| Метрика | До | Після |
|---|---|---|
| Час відгуку підказок | 1,5–2 с | близько 0,2 с |
| Потрібний товар у першій п’ятірці | 38% запитів | 87% |
| Звернення до підтримки щодо пошуку | базовий рівень | у 4 рази менше |
Перемикання пройшло без зупинки сервісу. Через місяць пошук перестав бути місцем, куди страшно заходити: користувачі частіше шукають напряму, а не гортають категорії, і частка сесій із пошуковим запитом зросла без змін в інтерфейсі.
Що робити, якщо пошук уже розгорнуто власними силами
Якщо пошук уже працює на вбудованих засобах — запитах напряму до бази або локальному індексі на пристрої, — починати варто не з переписування, а із замірів.
Дивимося, на якому обсязі каталогу час відповіді перестає вкладатися в комфортний, як поводиться видача при друкарських помилках, синонімах і зміні розкладки, що відбувається з базою при піковому навантаженні. Ці цифри й визначають, чи потрібен узагалі окремий пошуковий сервіс.
Далі розділяємо функціональність за вимогами. Підказки за введенням, фільтри, сортування та повнотекстовий пошук із ранжуванням — різні задачі, і частина з них спокійно залишається на вбудованому пошуку.
Зазвичай виносити має сенс лише повнотекстовий сценарій, де важливі релевантність, морфологія та стійкість до помилок введення, — решту чіпати не потрібно.
Перехід на пошуковий сервіс на кшталт Elasticsearch робимо без простою: індекси наповнюються паралельно з роботою застосунку, старий контур продовжує відповідати користувачам, а новий отримує той самий потік даних і відповідає в тіньовому режимі.
Ми звіряємо видачу на одному наборі запитів, поки розбіжності не пояснені, і лише потім перемикаємо частку трафіку — спочатку на внутрішніх працівниках, потім на невеликому відсотку аудиторії.
Своя команда при цьому не вимикається: вона тримає доменну логіку, правила обробки даних і пріоритети видачі, а ми закриваємо схему індексів, реплікацію, переіндексацію та поведінку при відмовах.
Відкат — це повернення частки трафіку та старий контур, який залишається живим до моменту, коли метрики нового стабільні. Тому міграція без простою — не обіцянка, а наслідок того, що дві схеми якийсь час працюють одночасно.
Технічні сумніви: запитання інженерів і техлідів
Сумніви щодо Elasticsearch у мобільному застосунку зводяться до п’яти тем: свіжість даних в індексі, поведінка при відмові пошукового сервісу, вимірюваність якості видачі, зростання обсягу та підтримка після передачі. Розберемо кожну.
Наскільки свіжі дані потрапляють у пошук?
Зміни йдуть в індекс через чергу, а не прямим записом із бази, тому збій пошуку не блокує замовлення. Затримка — секунди, у масових перезбирань каталогу хвилини, а її зростання ловить окреме оповіщення.
Що побачить користувач при відмові пошуку?
Кілька вузлів із репліками шардів — втрата одного видачу не перериває. Якщо недоступний весь пошук, застосунок переходить на резервний шлях: запит до бази за ключовими полями з базовими фільтрами замість екрана помилки.
Як перевірити якість видачі?
До релізу проганяємо еталонний набір запитів з очікуваними результатами й рахуємо повноту та точність. У продакшені дивимося запити без кліку та переформулювання: зростають — правимо аналізатор, синоніми й ваги полів.
Чи витримає пошук зростання обсягу даних?
Шарди розбиті за часом і типом контенту: зростання каталогу не потребує повної переіндексації. Старе їде в холодний індекс із меншою кількістю реплік, а регламент життєвого циклу чистить його автоматично.
Чи зможемо підтримувати пошук власними силами?
Передаємо мапінги, аналізатори, політики життєвого циклу, панелі моніторингу та оповіщення, розбираємо з командою типові операції: додати поле, переіндексувати, змінити ранжування. Далі контур ведете самі.
Обговоримо задачу: розберемо схему пошуку й повернемося з планом
Розмова про пошук швидко сходить на загальні слова, якщо прийти до неї без фактів.
Щоб обговорити задачу предметно, достатньо того, що вже є в проєкті: опису поточної схеми індексу, вивантаження реальних запитів користувачів, прикладів вдалої та невдалої видачі, обмежень щодо персональних даних і точок, де застосунок звертається до пошукового сервісу.
- сценарії пошуку: підказки в міру введення, виправлення друкарських помилок, пошук за фільтрами та сортуваннями;
- обсяг каталогу, темп його оновлення та вимоги до свіжості видачі;
- цільовий час відповіді на запит і поведінка застосунку, якщо пошук недоступний;
- правила доступу: які поля видно різним ролям і що індексувати не можна;
- поточна конфігурація Elasticsearch: індекси, аналізатори під мови застосунку, репліки;
- план випуску застосунку, до якого потрібно прив’язати роботи.
На дзвінку проходимо за цими даними й розбираємо, де саме втрачається релевантність: у розборі тексту, у наборі полів, у вагах чи в кешуванні на боці застосунку. Окремо фіксуємо, як переіндексація пройде без зупинки пошуку і на якій схемі відкочуємося, якщо якість видачі просів.
Повертаємося з планом робіт: склад робіт за етапами, порядок етапів, точки контролю та критерії приймання — наприклад, частка запитів, де потрібний товар або документ потрапляє в перші три результати. Опишіть задачу у вільній формі — повернемося з оцінкою та планом.







