Інтеграція Sphinx для пошуку на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Інтеграція Sphinx для пошуку на сайті
Середня
~2-3 робочих дні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Інтеграція Sphinx для пошуку на сайті

Sphinx Search та його активно розвивається форк Manticore Search — перевірені пошукові рушії з багаторічною історією в highload-проектах. Використовуються там, де важлива сумісність із MySQL-протоколом, зрілість рішення та прямий контроль над індексами. Manticore Search додав підтримку JSON-документів, колоночного сховища, HTTP API та RT-індексів реального часу.

Коли вибирають Sphinx / Manticore

  • Легаси-проекти з існуючою Sphinx-інфраструктурою
  • Потрібна MySQL-сумісність — підключення через стандартні MySQL-клієнти
  • Корпус в сотні мільйонів документів: новинні агрегатори, архіви
  • Повний контроль над токенізатором та морфологією
  • Інтеграція з існуючою MySQL/MariaDB-реплікацією

Manticore Search vs Sphinx

Характеристика Sphinx 3.x Manticore Search 6.x
Розробка Замалена Активна
RT-індекси Базові Повнофункціональні
JSON-документи Ні Так
HTTP API Ні Так (Elasticsearch-сумісний)
Колоночне сховище Ні Так
MySQL-протокол Так Так

Для нових проектів — краще Manticore Search.

Установка

# docker-compose.yml
services:
  manticore:
    image: manticoresearch/manticore:6.2.12
    environment:
      - EXTRA=1
    ports:
      - "9306:9306"   # MySQL-сумісний порт
      - "9308:9308"   # HTTP API
    volumes:
      - manticore_data:/var/lib/manticore
      - ./manticore.conf:/etc/manticoresearch/manticore.conf

Конфігурація індексу

# manticore.conf
index articles {
    type         = rt
    path         = /var/lib/manticore/articles

    rt_field     = title
    rt_field     = body
    rt_field     = author

    rt_attr_uint   = category_id
    rt_attr_bigint = created_at
    rt_attr_float  = rating
    rt_attr_string = slug

    morphology     = stem_ru, stem_en
    min_word_len   = 2
    expand_keywords = 1
    min_infix_len  = 3
    stopwords      = /etc/manticoresearch/stopwords_ru.txt
}

searchd {
    listen       = 0.0.0.0:9306:mysql41
    listen       = 0.0.0.0:9308:http
    log          = /var/log/manticore/searchd.log
    query_log    = /var/log/manticore/query.log
    max_matches  = 10000
}

Підключення через MySQL-клієнт (PHP)

Manticore приймає SQL на порту 9306 по MySQL-протоколу:

$pdo = new PDO('mysql:host=localhost;port=9306;charset=utf8', '', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Вставка документа:

$stmt = $pdo->prepare("
    INSERT INTO articles (id, title, body, author, category_id, created_at, rating)
    VALUES (:id, :title, :body, :author, :category_id, :created_at, :rating)
");
$stmt->execute([
    'id'          => $article->id,
    'title'       => $article->title,
    'body'        => strip_tags($article->content),
    'author'      => $article->user->name,
    'category_id' => $article->category_id,
    'created_at'  => $article->created_at->timestamp,
    'rating'      => $article->rating,
]);

Повнотекстовий пошук з вагами полів:

$stmt = $pdo->prepare("
    SELECT id, title, author, rating,
           WEIGHT() AS relevance
    FROM articles
    WHERE MATCH(:query)
      AND category_id = :category_id
    ORDER BY relevance DESC, rating DESC
    LIMIT :offset, :limit
    OPTION ranker=bm25, field_weights=(title=10, body=1, author=2)
");

HTTP API (Elasticsearch-сумісний)

# Індексація
curl -X POST 'http://localhost:9308/articles/_doc/1' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Заголовок статті",
    "body": "Текст статті",
    "category_id": 5
  }'

# Повнотекстовий пошук
curl -X POST 'http://localhost:9308/articles/_search' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": { "match": { "title": "пошук по сайту" } },
    "sort": [{ "_score": "desc" }],
    "size": 20
  }'

Синхронізація з основною БД

Batch-індексація через chunk:

public function handle(): void
{
    $pdo = $this->getManticoreConnection();

    Article::with('user', 'category')
        ->where('published', true)
        ->chunk(1000, function ($articles) use ($pdo) {
            $pdo->beginTransaction();
            foreach ($articles as $article) {
                $pdo->prepare("REPLACE INTO articles ...")->execute(
                    $this->toDocument($article)
                );
            }
            $pdo->commit();
        });
}

Event-driven оновлення через Observer:

class ArticleObserver
{
    public function saved(Article $article): void
    {
        ManticoreIndexJob::dispatch($article->id);
    }

    public function deleted(Article $article): void
    {
        ManticoreDeleteJob::dispatch($article->id);
    }
}

Морфологія російської мови

Sphinx/Manticore включає stem_ru. Для точнішої морфології використовуйте morphology = lemmatize_ru_all — вимагає окремих словників lemmatize. Це дозволяє знаходити «бігун» по запиту «біг».

Стоп-слова підключаються файлом — список прийменників, сполучників, частиць, які виключаються з індексу.

Підсвітка результатів

SELECT id, title,
       SNIPPET(body, :query,
               'limit=200, around=5, html_strip_mode=strip') AS excerpt
FROM articles
WHERE MATCH(:query)
LIMIT 20

SNIPPET() повертає фрагмент тексту із виділенням знайдених слів — готово для відображення в результатах пошуку.

Графіки робіт

Етап Час
Установка, конфігурація, схема індексу 1 день
Первинна індексація + синхронізатор 2 дні
API пошуку в додатку + тести 2 дні
UI: результати, сніппети, пагінація 1–2 дні

Усього: 6–7 робочих днів.