Если ваш сайт на PHP когда-нибудь тормозил из-за поиска по базе данных, вы знаете, как это больно. Elasticsearch решает эту проблему, но интеграция с PHP может показаться сложной. На самом деле всё проще, чем кажется: достаточно знать несколько приёмов и использовать правильную библиотеку.
Почему Elasticsearch, а не обычный SQL LIKE
Представьте, что у вас интернет-магазин с миллионом товаров. Пользователь вводит "красные кроссовки Nike". Если вы делаете запрос WHERE name LIKE '%красные%', база данных перебирает все записи. Это медленно и неточно.
Elasticsearch — это поисковый движок, который хранит данные в виде документов и умеет искать по ним с невероятной скоростью. Он анализирует текст, разбивает на слова, учитывает опечатки, синонимы и релевантность. Для PHP-разработчика это означает, что можно забыть о тормозах и сложных SQL-запросах.
Установка и подключение клиента
Для работы с Elasticsearch из PHP есть официальная библиотека elasticsearch-php. Устанавливается через Composer:
composer require elasticsearch/elasticsearch
После установки создаём клиент. По умолчанию Elasticsearch слушает порт 9200 на localhost.
<?php
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()
->setHosts(['localhost:9200'])
->build();
// Проверка соединения
$info = $client->info();
echo 'Elasticsearch версия: ' . $info['version']['number'];
Если всё сделано правильно, вы увидите номер версии. Если нет — проверьте, запущен ли Elasticsearch и доступен ли порт.
Индексация данных: первый шаг к поиску
Прежде чем искать, нужно создать индекс (аналог таблицы в SQL) и добавить документы. Допустим, у нас есть таблица products в MySQL. Мы хотим перенести товары в Elasticsearch.
<?php
// Создаём индекс с настройками
$params = [
'index' => 'products',
'body' => [
'settings' => [
'number_of_shards' => 1,
'number_of_replicas' => 0
],
'mappings' => [
'properties' => [
'name' => ['type' => 'text'],
'price' => ['type' => 'float'],
'description' => ['type' => 'text']
]
]
]
];
$client->indices()->create($params);
Теперь добавим документ. Можно вручную, но лучше использовать bulk-запросы для пакетной вставки.
<?php
$params = [
'index' => 'products',
'id' => 1,
'body' => [
'name' => 'Кроссовки Nike Air',
'price' => 8990,
'description' => 'Удобные красные кроссовки для бега'
]
];
$response = $client->index($params);
Для массовой загрузки из MySQL используйте цикл и bulk():
<?php
$bulkParams = ['body' => []];
$stmt = $pdo->query('SELECT id, name, price, description FROM products');
while ($row = $stmt->fetch()) {
$bulkParams['body'][] = [
'index' => [
'_index' => 'products',
'_id' => $row['id']
]
];
$bulkParams['body'][] = [
'name' => $row['name'],
'price' => (float)$row['price'],
'description' => $row['description']
];
}
$client->bulk($bulkParams);
Поиск: от простого к сложному
Самый простой поиск — match-запрос. Он ищет по указанному полю с учётом анализа текста.
<?php
$params = [
'index' => 'products',
'body' => [
'query' => [
'match' => [
'name' => 'красные кроссовки'
]
]
]
];
$response = $client->search($params);
foreach ($response['hits']['hits'] as $hit) {
echo $hit['_source']['name'] . ' - ' . $hit['_source']['price'] . ' руб.' . PHP_EOL;
}
Elasticsearch вернёт документы, отсортированные по релевантности. Если нужно искать по нескольким полям, используйте multi_match:
<?php
'query' => [
'multi_match' => [
'query' => 'красные кроссовки',
'fields' => ['name^2', 'description']
]
]
Символ ^2 означает, что поле name важнее в два раза.
Практические советы и лайфхаки
- Используйте фильтры для точных значений. Если нужно отфильтровать по цене или категории, применяйте
filterвнутриbool— это быстрее и не влияет на релевантность. - Настройте анализатор для русского языка. По умолчанию Elasticsearch не понимает морфологию. Установите плагин
analysis-icuили используйте встроенныйrussianанализатор. - Пагинация через
fromиsize. Но помните: глубокийfrom(более 10000) может тормозить. Для больших выборок используйтеsearch_after. - Обрабатывайте ошибки. Elasticsearch может быть недоступен. Оборачивайте вызовы в try-catch и логируйте.
Сравнение основных методов поиска:
| Метод | Когда использовать | Пример |
|---|---|---|
match |
Полнотекстовый поиск по одному полю | Поиск по названию товара |
multi_match |
Поиск по нескольким полям | Название + описание |
term |
Точное совпадение (без анализа) | Фильтр по статусу заказа |
bool |
Комбинация условий (must, should, filter) | Сложные запросы с фильтрацией |
Что в итоге
Elasticsearch и PHP — отличный тандем для создания быстрого и умного поиска. Главное — правильно настроить индекс, использовать bulk-индексацию и не забывать про анализаторы. Начните с простых запросов, постепенно усложняя их. И помните: поиск должен помогать пользователю, а не заставлять его ждать.
Если вы только начинаете, попробуйте интегрировать Elasticsearch в небольшой проект — например, для поиска по статьям блога. Уверен, результат вас приятно удивит.



