Типова ситуація: інтернет-магазин з 50 000 товарів, пошук через LIKE-запити до MySQL — час відповіді 5–10 секунд. Клієнти йдуть, конверсія падає. Рішення — Algolia, пошуковий SaaS з власною інфраструктурою індексації та typo-tolerant пошуком. Замість написання full-text search на PostgreSQL або Elasticsearch ми беремо готовий індекс, API та InstantSearch-компоненти для фронтенду. Основна робота — налагодити синхронізацію даних та налаштувати релевантність, щоб перші результати були релевантні. Наша команда має 5+ років досвіду з Algolia, виконали понад 50 інтеграцій, гарантуючи стабільність і швидкість пошуку.
Чому Algolia краще за аналоги?
Algolia дозволяє індексування даних у вигляді JSON-об'єктів з атрибутами. Пошук іде за налаштованими полями з урахуванням помилок, синонімів та ваг. Кожен об'єкт повинен мати унікальний objectID. Безкоштовний план: 10 000 записів, 10 000 пошукових запитів на місяць — для невеликих сайтів вистачає. Платні плани розширюють ліміти. Вартість розраховується індивідуально. Алгоритм пошуку в Algolia оптимізований для роботи з помилками, синонімами та ранжуванням, що дає релевантні результати миттєво (1–10 мс). На відміну від LIKE-запитів у SQL, які сканують всю таблицю, Algolia використовує інвертований індекс та кешування на CDN. Algolia в 10 разів швидше за Elasticsearch та в 100 разів швидше за стандартний SQL-пошук.
Порівняльна таблиця
| Параметр | Algolia | Elasticsearch | PostgreSQL full-text |
|---|---|---|---|
| Час відповіді | 1–10 мс | 10–100 мс | 10–100+ мс |
| Стійкість до помилок | вбудована | налаштовується | немає |
| Складність налаштування | низька | висока | середня |
| Вартість для малого бізнесу | безкоштовно до 10k записів | потребує сервера | безкоштовно + хостинг |
| Frontend компоненти | готові (React, Vue) | потребує розробки | потребує розробки |
Згідно з офіційною документацією Algolia, typo-tolerant пошук дозволяє знаходити товари навіть при помилках введення.
Як інтегрувати Algolia?
Налаштування релевантності
Релевантність пошуку керується через налаштування індексу: порядок searchableAttributes задає вагу полів, ranking визначає фактори сортування (помилки, відстань, популярність). Додатково можна використовувати customRanking — наприклад, за датою оновлення. Через Dashboard або API виставляємо параметри:
$index->setSettings([
'searchableAttributes' => [
'name',
'unordered(category)',
'unordered(description)',
'unordered(tags)',
],
'attributesForFaceting' => [
'filterOnly(price)',
'category',
'in_stock',
],
'attributesToRetrieve' => [
'objectID', 'name', 'price', 'category', 'image_url', 'slug', 'in_stock',
],
'attributesToHighlight' => ['name', 'category'],
'typoTolerance' => true,
'minWordSizefor1Typo' => 4,
'minWordSizefor2Typos' => 8,
'ranking' => [
'typo', 'geo', 'words', 'filters', 'proximity', 'attribute',
'exact', 'custom',
],
'customRanking' => ['desc(updated_at)'],
]);
Синхронізація даних через Laravel Observer
Індекс повинен оновлюватись при зміні даних. Observer в Laravel:
class ProductObserver {
private SearchClient $algolia;
public function __construct() {
$this->algolia = SearchClient::create(
config('algolia.app_id'),
config('algolia.admin_api_key')
);
}
public function saved(Product $product): void {
$this->algolia->initIndex('products')->saveObject(
$this->toAlgoliaRecord($product)
);
}
public function deleted(Product $product): void {
$this->algolia->initIndex('products')->deleteObject('product-' . $product->id);
}
private function toAlgoliaRecord(Product $product): array {
return [
'objectID' => 'product-' . $product->id,
'name' => $product->name,
'description' => Str::limit(strip_tags($product->description), 300),
'category' => $product->category->name,
'tags' => $product->tags->pluck('name')->toArray(),
'price' => (float)$product->price,
'in_stock' => $product->stock > 0,
'image_url' => $product->thumbnail_url,
'slug' => $product->slug,
'updated_at' => $product->updated_at->timestamp,
];
}
}
Реєстрація в AppServiceProvider:
Product::observe(ProductObserver::class);
React пошук
Для React пошук реалізується через бібліотеку react-instantsearch. Приклад:
import algoliasearch from 'algoliasearch/lite';
import {
InstantSearch,
SearchBox,
Hits,
RefinementList,
Pagination,
Highlight,
Configure,
} from 'react-instantsearch';
const searchClient = algoliasearch(
import.meta.env.VITE_ALGOLIA_APP_ID,
import.meta.env.VITE_ALGOLIA_SEARCH_KEY
);
const ProductHit: React.FC<{ hit: ProductRecord }> = ({ hit }) => (
<a href={`/products/${hit.slug}`} className="flex gap-3 p-3 hover:bg-gray-50 rounded">
<img src={hit.image_url} alt={hit.name} className="w-12 h-12 object-cover rounded" />
<div>
<p className="font-medium">
<Highlight attribute="name" hit={hit} />
</p>
<p className="text-sm text-gray-500">
<Highlight attribute="category" hit={hit} />
</p>
<p className="font-semibold">{hit.price.toLocaleString()} ₴</p>
</div>
</a>
);
export const SiteSearch: React.FC = () => (
<InstantSearch searchClient={searchClient} indexName="products">
<Configure hitsPerPage={20} filters="in_stock:true" />
<SearchBox
placeholder="Пошук товарів..."
classNames={{ input: 'w-full border rounded-lg px-4 py-2' }}
/>
<div className="flex gap-6 mt-4">
<aside className="w-48 shrink-0">
<p className="font-medium mb-2">Категорія</p>
<RefinementList attribute="category" />
</aside>
<div className="flex-1">
<Hits hitComponent={ProductHit} />
<Pagination className="mt-4" />
</div>
</div>
</InstantSearch>
);
Algolia аналітика
Algolia збирає кліки та конверсії для покращення релевантності. Підключення:
import { createInsightsMiddleware } from 'instantsearch.js/es/middlewares';
import aa from 'search-insights';
aa('init', {
appId: import.meta.env.VITE_ALGOLIA_APP_ID,
apiKey: import.meta.env.VITE_ALGOLIA_SEARCH_KEY,
useCookie: true,
});
// В InstantSearch
<InstantSearch
searchClient={searchClient}
indexName="products"
middlewares={[createInsightsMiddleware({ insightsClient: aa })]}
insights
>
Додаткова інформація
Плани та вартість
| План | Записів | Запитів/міс | Вартість |
|---|---|---|---|
| Безкоштовний | 10 000 | 10 000 | безкоштовно |
| Стартовий | 100 000 | 100 000 | платний |
| Бізнес | 1 000 000 | 1 000 000 | індивідуально |
Вартість базової Algolia інтеграції — від 500 $, повного пакету з аналітикою — від 1500 $.
Покрокова інструкція з інтеграції
- Створіть індекс у Algolia Dashboard.
- Налаштуйте атрибути та фасети.
- Реалізуйте Observer на бекенді (Laravel).
- Розробіть фронтенд з InstantSearch (React).
- Підключіть аналітику.
- Протестуйте та оптимізуйте релевантність.
Характерні помилки при інтеграції
- Некоректний
objectID: якщо він не унікальний, дані перезаписуються. Завжди генеруйте на основі ID запису. - Відсутність атрибутів для фасетів: щоб фасетна фільтрація працювала, потрібно вказати
attributesForFaceting. - Ігнорування
customRanking: без нього результати сортуються лише за релевантністю — для комерційних сайтів краще додати врахування популярності або дати. - Неправильне налаштування
typoTolerance— може призвести до нерелевантних результатів.
Чек-лист перед запуском
- Перевірити всі обов'язкові атрибути індексу.
- Налаштувати права доступу: search-only API key на фронтенді, admin key – тільки на бекенді.
- Протестувати синхронізацію на тестових даних.
- Увімкнути аналітику та відстежувати перші 1000 запитів.
- Оптимізувати видачу за допомогою A/B-тестів (на платному плані).
Що входить в роботу?
- Налаштування індексу Algolia: структура атрибутів, релевантність, фільтри.
- Автоматична синхронізація даних через Observer або вебхуки.
- Розробка UI пошуку на React (або Vue) з InstantSearch, включаючи фасетну фільтрацію.
- Підключення аналітики для покращення ранжування.
- Документація та навчання команди.
- Гарантія стабільної роботи та підтримка після запуску.
- Реалізація пошуку під ключ: від налаштування індексу до деплою.
Строки реалізації
Базова інтеграція з індексацією через Observer та пошуком на фронтенді: 1–2 дні. Додавання фасетної фільтрації, аналітики та налаштування релевантності: 3–4 дні. Мультимовні індекси з синхронізацією: плюс 1–2 дні.
Замовте впровадження Algolia вже сьогодні — отримайте консультацію та попередню оцінку вартості. Зв'яжіться з нами, щоб обговорити ваш проєкт.







