在Yii框架中集成Elasticsearch可以快速实现高性能的全文检索功能,满足项目中大量文档、内容的快速查询需求。整个过程主要分为环境准备、扩展配置、索引管理和检索实现四个部分,下面逐步展开说明。

环境准备
首先确保服务器已经安装并启动了Elasticsearch服务,建议版本选择7.x及以上,同时PHP环境需要支持curl扩展,因为Elasticsearch的PHP客户端依赖curl进行接口调用。可以通过命令行执行curl -X GET "localhost:9200"验证Elasticsearch是否正常运行,如果返回集群信息则说明服务启动成功。
安装Yii的Elasticsearch扩展
Yii官方提供了Elasticsearch的扩展包,推荐使用Composer进行安装,在项目根目录执行以下命令:
composer require yiisoft/yii2-elasticsearch
安装完成后需要在Yii的配置文件中进行组件配置,打开config/web.php,在components数组中添加Elasticsearch组件配置:
<?php
return [
// 其他配置项
'components' => [
// 其他组件
'elasticsearch' => [
'class' => 'yiielasticsearchConnection',
'nodes' => [
['http_address' => '127.0.0.1:9200'],
// 如果有多个节点可以继续添加
],
// 可选配置,设置索引前缀,避免索引名冲突
'indexPrefix' => 'yii_',
],
],
];
定义Elasticsearch模型
Yii中操作Elasticsearch需要使用继承自yiielasticsearchActiveRecord的模型类,下面以文章检索为例,创建一个Article模型:
<?php
namespace appmodels;
use yiielasticsearchActiveRecord;
class Article extends ActiveRecord
{
/**
* 定义索引名,对应Elasticsearch中的索引
* @return string
*/
public static function index()
{
return 'article';
}
/**
* 定义索引类型,Elasticsearch 7.x及以上版本类型默认为_doc,这里直接返回
* @return string
*/
public static function type()
{
return '_doc';
}
/**
* 定义索引的映射规则,指定字段类型和分词器
* @return array
*/
public static function mapping()
{
return [
'properties' => [
'id' => ['type' => 'integer'],
'title' => [
'type' => 'text',
// 使用ik分词器进行中文分词,需要先安装ik插件
'analyzer' => 'ik_max_word',
'search_analyzer' => 'ik_smart'
],
'content' => [
'type' => 'text',
'analyzer' => 'ik_max_word',
'search_analyzer' => 'ik_smart'
],
'create_time' => ['type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss'],
'category_id' => ['type' => 'integer']
]
];
}
/**
* 获取模型属性,对应索引中的字段
* @return array
*/
public function attributes()
{
return ['id', 'title', 'content', 'create_time', 'category_id'];
}
/**
* 规则定义,用于数据验证
* @return array
*/
public function rules()
{
return [
[['id', 'category_id'], 'integer'],
[['title', 'content'], 'string'],
[['create_time'], 'safe']
];
}
}
创建和更新索引
模型定义完成后,需要创建对应的Elasticsearch索引并应用映射规则,可以在控制器或者命令行脚本中执行以下代码:
<?php // 创建索引 Article::createIndex(); // 更新索引映射 Article::updateMapping(); // 如果需要删除索引可以使用 Article::deleteIndex();
如果需要将已有的MySQL数据同步到Elasticsearch中,可以编写同步脚本,遍历数据库中的数据批量写入索引:
<?php
use appmodelsArticle;
use appmodelsArticle as DbArticle;
// 从数据库获取所有文章数据
$dbArticles = DbArticle::find()->all();
foreach ($dbArticles as $dbArticle) {
$esArticle = new Article();
$esArticle->attributes = [
'id' => $dbArticle->id,
'title' => $dbArticle->title,
'content' => $dbArticle->content,
'create_time' => $dbArticle->create_time,
'category_id' => $dbArticle->category_id
];
// 保存数据到Elasticsearch
$esArticle->save();
}
实现全文检索功能
完成索引配置和数据同步后,就可以实现全文检索功能了,下面是一个简单的检索示例,根据关键词搜索文章标题和内容:
<?php
use appmodelsArticle;
use yiielasticsearchQuery;
// 要搜索的关键词
$keyword = 'Yii框架教程';
// 创建查询对象
$query = new Query();
$query->from(Article::index(), Article::type())
->query([
'multi_match' => [
'query' => $keyword,
// 搜索的字段,这里搜索title和content
'fields' => ['title', 'content']
]
])
// 可选,设置分页
->offset(0)
->limit(10);
// 执行查询获取结果
$results = $query->search();
// 获取匹配的文章ID列表
$articleIds = array_column($results['hits']['hits'], '_id');
// 可以根据ID从数据库获取完整的文章数据,也可以直接使用Elasticsearch返回的数据
$articles = [];
foreach ($results['hits']['hits'] as $hit) {
$articles[] = $hit['_source'];
}
进阶配置说明
自定义分词器配置
如果需要自定义分词规则,可以在创建索引时指定分词器配置,修改mapping方法或者在创建索引时传入settings参数:
<?php
public static function mapping()
{
return [
'settings' => [
'analysis' => [
'analyzer' => [
'custom_analyzer' => [
'type' => 'custom',
'tokenizer' => 'ik_max_word',
'filter' => ['lowercase']
]
]
]
],
'properties' => [
'title' => [
'type' => 'text',
'analyzer' => 'custom_analyzer'
]
]
];
}
数据实时同步
为了保证Elasticsearch和数据库的数据一致性,可以在文章的增删改操作中同步更新Elasticsearch索引,比如在afterSave和afterDelete方法中添加同步逻辑:
<?php
namespace appmodels;
use yiidbActiveRecord as DbActiveRecord;
use yiielasticsearchActiveRecord;
class Article extends DbActiveRecord
{
// 数据库模型原有逻辑
/**
* 保存后同步到Elasticsearch
* @param bool $insert
* @param array $changedAttributes
*/
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
$esArticle = ArticleEs::findOne($this->id);
if (!$esArticle) {
$esArticle = new ArticleEs();
}
$esArticle->attributes = $this->attributes;
$esArticle->save();
}
/**
* 删除后同步删除Elasticsearch中的数据
*/
public function afterDelete()
{
parent::afterDelete();
$esArticle = ArticleEs::findOne($this->id);
if ($esArticle) {
$esArticle->delete();
}
}
}
以上就是在Yii框架中集成Elasticsearch实现全文检索的完整流程,开发者可以根据项目的实际需求调整索引配置和检索逻辑,满足不同的搜索场景需求。
YiiElasticsearchfull_text_searchphp修改时间:2026-06-28 02:48:43