Кожне десяте замовлення в інтернет-магазині втрачається через неправильно введену адресу. Згідно з дослідженням DataInsight, до 15% посилок не доходять до отримувача з першої спроби — найчастіше через помилки в адресі. Користувач не знає точної вулиці, плутає район, пропускає корпус. Ми вирішуємо це за допомогою автодоповнення адрес на основі ФІАС. Наш досвід — 5 років і 20 успішних проектів. Для 10 інтернет-магазинів кількість помилок знизилася з 15% до 1%. Пропонуємо два шляхи: хмарний сервіс DaData або власна інфраструктура на PostgreSQL. Власний сервер окупається при навантаженні від 5 тисяч запитів на день. Розберемо технічні деталі: від завантаження дампів до фронтенду. Використовуємо дельта-оновлення, GIN-індекси та кешування.
Як інтегрувати ФІАС без посередників?
Пряма інтеграція виправдана в трьох випадках: вимоги ІБ не дозволяють відправляти адреси у зовнішні API, очікується високе навантаження (десятки тисяч запитів на добу), потрібна кастомна логіка пошуку. В інших випадках простіше і дешевше використовувати DaData.
Отримання та завантаження дампів
Актуальні дампи публікуються на офіційному сайті ФІАС. Доступні повна база (XML, декілька десятків архівів, загальний обсяг стиснутих даних — близько 2 ГБ) та дельта-оновлення (щотижневі). Формат ГАР трохи відрізняється, але принципи ті самі.
Мінімальний набір таблиць для адресних підказок:
-
AS_ADDR_OBJ— регіони, райони, міста, вулиці -
AS_HOUSES— будинки, будівлі, корпуси -
AS_HIERARCHY— ієрархічні зв'язки об'єктів -
AS_ADDR_OBJ_PARAMS— додаткові параметри (поштовий індекс)
Перше завантаження повного дампа в PostgreSQL через php-скрипт або python-парсер займає 3–6 годин. Дельта-оновлення — 10–30 хвилин.
Структура таблиць та індекси
CREATE TABLE addr_obj ( id UUID PRIMARY KEY, object_id BIGINT, name TEXT NOT NULL, type_name TEXT, level SMALLINT, is_active BOOLEAN DEFAULT true ); CREATE TABLE houses ( id UUID PRIMARY KEY, object_id BIGINT, addr_obj_id BIGINT, house_num TEXT, build_num TEXT, struct_num TEXT, is_active BOOLEAN DEFAULT true ); CREATE INDEX idx_addr_obj_name_fts ON addr_obj USING GIN (to_tsvector('russian', name)); CREATE INDEX idx_hierarchy_parent ON hierarchy(parent_obj_id); CREATE INDEX idx_hierarchy_child ON hierarchy(object_id); Без GIN-індексу пошук по 30+ млн записів буде нестерпно повільним. Документація PostgreSQL по GIN-індексах рекомендує саме такий підхід для повнотекстового пошуку російською мовою.
API для підказок
Простий endpoint на PHP/Laravel, який приймає рядок і повертає список варіантів:
public function suggest(Request $request): JsonResponse { $query = trim($request->input('q', '')); if (mb_strlen($query) < 2) { return response()->json([]); } $results = DB::select(" SELECT ao.name, ao.type_name, ao.level, h.path_name FROM addr_obj ao JOIN addr_hierarchy h ON h.object_id = ao.object_id WHERE to_tsvector('russian', ao.name) @@ plainto_tsquery('russian', ?) AND ao.is_active = true ORDER BY ao.level, ao.name LIMIT 10 ", [$query]); return response()->json($results); } Для введення будинків запит складніший — потрібно спочатку знайти вулицю за її object_id, потім шукати будинки за addr_obj_id. У нашій практиці середній час виконання такого складеного запиту не перевищує 80 мс після прогріву кешу.
Фронтенд: підключення підказок
На стороні браузера — стандартна логіка debounce + fetch:
let timer; input.addEventListener('input', () => { clearTimeout(timer); timer = setTimeout(async () => { const q = input.value.trim(); if (q.length < 2) return; const res = await fetch(`/api/fias/suggest?q=${encodeURIComponent(q)}`); const data = await res.json(); renderDropdown(data); }, 250); }); Затримка 250 мс виключає запит на кожен натиснутий символ. Для покращення UX ми додаємо індикатор завантаження і обробляємо помилки — користувач не повинен бачити порожній дропдаун при мережевому збої.
Коли власна інфраструктура виправдана?
Порівняємо підходи:
| Критерій | Власний сервер ФІАС | DaData |
|---|---|---|
| Контроль даних | Повний | Обмежений |
| Вимоги до інфраструктури | Сервер 8 ГБ RAM, 50 ГБ SSD | Не потрібен |
| Час на впровадження | 1–2 дні на первинне завантаження | Кілька годин |
| Оновлення даних | Автоматичне через дельти | Автоматичне |
Якщо обсяг запитів високий, власний сервер дешевший у довгостроковій перспективі. Наприклад, при 10 000 запитів на день DaData обійдеться приблизно в 3000 руб/міс, а власний сервер — близько 1000 руб/міс з урахуванням хостингу.
Продуктивність API
| Параметр | Значення |
|---|---|
| Кількість записів у повному дампі | ~30 млн |
| Розмір бази даних (з індексами) | ~10 ГБ |
| Середній час запиту (прості підказки) | <30 мс |
| Середній час запиту (з ієрархією) | <80 мс |
| Час завантаження повного дампа | 3–6 годин |
Процес роботи
- Аналіз вимог — визначаємо навантаження, необхідність закритого контуру, обираємо підхід.
- Підготовка інфраструктури — налаштовуємо сервер (Linux, PostgreSQL, Docker) або підключаємося до DaData.
- Завантаження та індексація дампу — завантажуємо повний дамп ФІАС/ГАР, створюємо GIN-індекси.
- Розробка REST API — реалізуємо endpoint для підказок з урахуванням ієрархії.
- Інтеграція фронтенду — підключаємо AJAX-запити до API, налаштовуємо debounce та рендер.
- Автооновлення — налаштовуємо cron для щоденного завантаження та застосування дельт.
- Тестування та документація — перевіряємо коректність підказок, пишемо API-документацію.
Що входить у роботу
- документація по інтеграції (API-специфікація, опис таблиць)
- доступ до API (якщо розгортаємо на вашому сервері) або інструкція по підключенню до DaData
- скрипти для автооновлення даних
- технічна підтримка 2 тижні після запуску
- навчання розробників по роботі з рішенням
Типові помилки при самостійній інтеграції
Часті помилки при самостійній інтеграції
- Завантаження неповного набору таблиць — пропускають
AS_HIERARCHY, через що неможливо вибудувати ланцюжок регіон→місто→вулиця - Відсутність повнотекстового індексу — пошук гальмує до 10 секунд
- Ігнорування дельта-оновлень — дані застарівають, користувачі бачать неактуальні адреси
- Неправильна нормалізація введення — наприклад, не враховують відмінки ("Києві" не знайде "Київ")
Ми гарантуємо, що після нашої роботи підказки працюють коректно, без лагів і з актуальними даними. Отримайте консультацію — зв'яжіться з нами.
Терміни та вартість
Орієнтовні терміни — від 3 до 7 робочих днів, залежно від складності. Вартість розраховується індивідуально. Замовте оцінку вашого проекту за один день — ми підготуємо комерційну пропозицію.







