Інтеграція Typesense для пошуку на сайті
Typesense — рушій пошуку з відкритим кодом, написаний на C++. Позиціонується як хмарна альтернатива Algolia з можливістю self-hosted розгортання. Час відповіді стабільно нижче 50 мс навіть на мільйонах документів. Підтримує векторний пошук через HNSW, семантичний пошук через embeddings та класичний повнотекстовий пошук.
Відмінності від Meilisearch
| Характеристика | Typesense | Meilisearch |
|---|---|---|
| Мова | C++ | Rust |
| Кластеризація | Вбудована (Raft) | Відсутня в OSS |
| Векторний пошук | Так (HNSW) | Так (v1.6+) |
| Geo-пошук | Нативний | Так |
| Аналітика запитів | Вбудована | Через сторонні інструменти |
| Строга схема | Обов'язкова | Опціональна |
Установка
# docker-compose.yml
services:
typesense:
image: typesense/typesense:0.25.2
command: >
--data-dir /data
--api-key=${TYPESENSE_API_KEY}
--listen-port=8108
--enable-cors
volumes:
- typesense_data:/data
ports:
- "8108:8108"
Схема коллекції
Typesense використовує строгу схему. Визначаємо до додавання документів:
{
"name": "products",
"fields": [
{ "name": "id", "type": "string" },
{ "name": "name", "type": "string" },
{ "name": "description", "type": "string" },
{ "name": "price", "type": "float", "facet": true },
{ "name": "category", "type": "string", "facet": true },
{ "name": "brand", "type": "string", "facet": true },
{ "name": "in_stock", "type": "bool", "facet": true },
{ "name": "rating", "type": "float", "optional": true },
{ "name": "location", "type": "geopoint","optional": true }
],
"default_sorting_field": "rating"
}
PHP інтеграція
composer require php-http/guzzle7-adapter typesense/typesense-php
use Typesense\Client;
$client = new Client([
'api_key' => env('TYPESENSE_API_KEY'),
'nodes' => [['host' => 'localhost', 'port' => '8108', 'protocol' => 'http']],
'connection_timeout_seconds' => 2,
]);
// Upsert документа
$client->collections['products']->documents->upsert([
'id' => (string) $product->id,
'name' => $product->name,
'description' => strip_tags($product->description),
'price' => (float) $product->price,
'category' => $product->category->slug,
'brand' => $product->brand->name,
'in_stock' => $product->stock > 0,
'rating' => (float) $product->rating,
]);
Пошук із фасетами
$results = $client->collections['products']->documents->search([
'q' => $query,
'query_by' => 'name,description,brand',
'query_by_weights' => '3,1,2',
'filter_by' => 'in_stock:true && price:[100..5000]',
'facet_by' => 'category,brand,price',
'max_facet_values' => 20,
'sort_by' => 'rating:desc',
'per_page' => 20,
'page' => 1,
]);
// $results['facet_counts'] — агрегації для відображення фільтрів
Векторний пошук
Typesense приймає embedding-вектори для семантичного пошуку. Модель генерації еméddingів — на стороні додатку:
// Індексація з вектором (OpenAI text-embedding-3-small, dim=1536)
$client->collections['products']->documents->upsert([
'id' => '123',
'name' => 'Ноутбук Dell XPS 15',
'embedding' => $vector, // float[]
]);
// Гібридний пошук: текст + вектор
$results = $client->collections['products']->documents->search([
'q' => 'мощный ноутбук для роботи',
'query_by' => 'name,embedding',
'vector_query' => 'embedding:([], k:10)',
]);
Geo-пошук
Поле geopoint приймає [lat, lng]. Пошук по радіусу:
$results = $client->collections['stores']->documents->search([
'q' => '*',
'query_by' => 'name',
'filter_by' => 'location:(55.7558, 37.6173, 10 km)',
'sort_by' => 'location(55.7558, 37.6173):asc',
]);
Аналітика запитів
Typesense записує статистику поискових запитів: топ запитів, запити без результатів. Корисно для SEO-аналізу та настройки синонімів.
Графіки робіт
| Етап | Час |
|---|---|
| Розгортання, схема коллекції | 1 день |
| Індексатор + синхронізація | 2 дні |
| Пошук із фасетами на frontend | 2–3 дні |
| Векторний пошук (опціонально) | 2 дні додатково |
| Тести, релевантність | 1 день |
Стандартна інтеграція без векторного пошуку — 6–7 робочих днів.







