Кожне десяте замовлення в інтернет-магазині втрачається через неправильно введену адресу. Згідно з дослідженням 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 обійдеться приблизно в $27–39/міс, а власний сервер — близько $9–13/міс з урахуванням хостингу.
Продуктивність 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 робочих днів, залежно від складності. Вартість розраховується індивідуально. Замовте оцінку вашого проекту за один день — ми підготуємо комерційну пропозицію.







