Полнотекстовый поиск — это как поиск иголки в стоге сена, только стог огромный, а иголка может быть где угодно. Если ваш сайт на Yii страдает от медленных запросов и неточных результатов, Elasticsearch придёт на помощь. В этой статье мы разберём, как подружить Yii с Elasticsearch и настроить поиск, который работает быстро и релевантно.
Что такое Elasticsearch и зачем он нужен в Yii
Elasticsearch — это поисковый движок на основе Lucene. Он хранит данные в виде JSON-документов и умеет искать по ним с высокой скоростью. В Yii мы привыкли использовать базы данных вроде MySQL, но для полнотекстового поиска они не всегда эффективны. Elasticsearch же индексирует текст, разбивает его на токены, применяет стемминг (приведение слов к основе) и ранжирует результаты по релевантности.
Представьте, что у вас интернет-магазин с миллионом товаров. Пользователь вводит «красные кроссовки Nike». MySQL с LIKE будет перебирать все записи и тормозить. Elasticsearch найдёт нужное за миллисекунды, даже если в названии товара написано «кроссовки Nike красного цвета».
Установка и настройка Elasticsearch
Сначала установим Elasticsearch. Скачайте дистрибутив с официального сайта и распакуйте. Для Linux/macOS запустите:
./bin/elasticsearch
Для Windows — bin\elasticsearch.bat. По умолчанию Elasticsearch слушает порт 9200. Проверьте работу:
curl http://localhost:9200
Вы должны увидеть JSON с информацией о кластере. Если всё ок, переходим к Yii.
Подключаем Elasticsearch к Yii
Для интеграции используем официальное расширение yiisoft/yii2-elasticsearch. Установим через Composer:
composer require --prefer-dist yiisoft/yii2-elasticsearch
Теперь настроим компонент в конфиге приложения (например, config/web.php):
return [
'components' => [
'elasticsearch' => [
'class' => 'yii\elasticsearch\Connection',
'nodes' => [
['http_address' => '127.0.0.1:9200'],
],
],
],
];
Всё, соединение готово. Теперь можно выполнять запросы через Yii::$app->elasticsearch.
Индексация данных в Elasticsearch
Elasticsearch хранит данные в индексах. Индекс — это аналог таблицы в базе данных. Создадим индекс для товаров. В Yii это делается через компонент:
$index = Yii::$app->elasticsearch->createCommand()->index('products');
$index->create([
'settings' => [
'number_of_shards' => 1,
'number_of_replicas' => 0,
],
'mappings' => [
'properties' => [
'name' => ['type' => 'text'],
'description' => ['type' => 'text'],
'price' => ['type' => 'float'],
],
],
]);
Теперь заполним индекс данными из базы. Например, возьмём все товары и отправим их в Elasticsearch:
$products = Product::find()->all();
foreach ($products as $product) {
Yii::$app->elasticsearch->createCommand()->index('products')->add($product->id, [
'name' => $product->name,
'description' => $product->description,
'price' => $product->price,
]);
}
Для больших объёмов данных используйте пакетную индексацию (bulk). Это значительно быстрее.
Поиск с помощью Elasticsearch в Yii
Теперь самое интересное — поиск. Допустим, пользователь ищет «кроссовки». Выполним запрос:
$query = Yii::$app->elasticsearch->createCommand()->search('products');
$query->query([
'multi_match' => [
'query' => 'кроссовки',
'fields' => ['name', 'description'],
],
]);
$results = $query->all();
В $results будет массив документов с полем _source, где лежат исходные данные. Можно вывести их в представлении.
Чтобы поиск был умнее, используйте анализаторы. Например, русский анализатор умеет учитывать морфологию. Добавим его в настройки индекса:
'settings' => [
'analysis' => [
'analyzer' => [
'my_analyzer' => [
'type' => 'custom',
'tokenizer' => 'standard',
'filter' => ['lowercase', 'russian_morphology', 'english_morphology'],
],
],
],
],
И применим его к полям:
'name' => [
'type' => 'text',
'analyzer' => 'my_analyzer',
],
Теперь запрос «кроссовки» найдёт и «кроссовок», и «кроссовочный».
fuzziness в запросе, чтобы находить слова с опечатками. Например, 'fuzziness' => 'AUTO' позволит найти «кросовки» вместо «кроссовки».
Сравнение возможностей Elasticsearch и MySQL
Чтобы понять, когда стоит использовать Elasticsearch, взгляните на таблицу:
| Критерий | MySQL (LIKE) | Elasticsearch |
|---|---|---|
| Скорость поиска | Медленно на больших данных | Очень быстро |
| Релевантность | Нет | Высокая (ранжирование) |
| Морфология | Нет | Есть анализаторы |
| Опечатки | Нет | Fuzzy-поиск |
Практические советы по интеграции
- Синхронизация данных. При изменении записи в базе обновляйте документ в Elasticsearch. Можно использовать поведение (behavior) в Yii.
- Обработка ошибок. Elasticsearch может быть недоступен. Оборачивайте запросы в try-catch и предусмотрите fallback на обычный поиск по базе.
- Мониторинг. Следите за состоянием кластера через
_cluster/health. - Безопасность. Не оставляйте Elasticsearch открытым в интернет без аутентификации. Используйте X-Pack или обратный прокси.
Заключение
Интеграция Yii с Elasticsearch — это не так сложно, как кажется. Вы получаете мощный полнотекстовый поиск, который работает быстро и умеет прощать опечатки. Главное — правильно настроить анализаторы и не забывать синхронизировать данные. Попробуйте на небольшом проекте, и вы оцените разницу.
Что в итоге: Elasticsearch + Yii = быстрый и релевантный поиск, который порадует пользователей. Дерзайте!


