应改用 theflyingzamboni/yii2-elasticsearch 扩展,它兼容 yii 2.0.42+ 和 es 7.x/8.x;原版已废弃,不支持新版本,易报错或静默丢数据。

别用 yiisoft/yii2-elasticsearch 原版扩展 —— 它已废弃,且在 Yii 2.0.40+ 或 ES 7.x/8.x 下大概率报错或静默丢数据。
装哪个扩展才真正能用
原扩展在 Packagist 被标记为 abandoned,最新稳定版只支持到 Yii 2.0.38 和 ES 6.x。你如果用的是 PHP 8.0+、Yii ≥2.0.42、ES 7.10+ 或 8.x,硬装会直接失败或连不上。
- 确认当前 Yii 版本:
php yii version - 推荐改用社区维护分支:
composer require --prefer-dist theflyingzamboni/yii2-elasticsearch(兼容 Yii 2.0.42+、ES 7.x/8.x) - 安装后务必清空缓存:
rm -rf runtime/cache/*,否则可能报Class 'yii\elasticsearch\Connection' not found
连不上 Elasticsearch 的真实原因
不是“配置写错了”,而是协议和认证没对齐。ES 7.10+ 默认禁用 HTTP 访问,8.x 更彻底移除 Transport 协议,而 Yii 扩展默认走 HTTP + Basic Auth。
- 检查
elasticsearch.yml是否启用 HTTP:必须有http.port: 9200和http.host: 0.0.0.0(开发环境) - 若启用了安全模块(如 Elastic Cloud、自建开启
xpack.security.enabled: true),必须配auth参数:"auth" => ["elastic", "your_password"] - ES 8.x 默认强制 HTTPS:本地开发可临时关安全模块(
xpack.security.enabled: false),否则得用https://地址 +"sslPeerVerification" => false
ActiveRecord::find()->query() 返回空?不是没数据,是字段没对上
这是最常被忽略的坑:yii\elasticsearch\ActiveRecord 默认只取 _source 字段,且要求 mapping 中字段类型与 PHP 类型严格匹配。哪怕一个字段是 keyword 类型,你在模型里声明为 string,整条记录就会被 ORM 静默过滤掉。
- 先用
curl -XGET 'http://127.0.0.1:9200/your_index/_search?pretty'看原始响应,确认_source结构和字段类型 - 在 ActiveRecord 类中显式写
attributes(),把 mapping 里的字段名逐个列出来,不要依赖自动推断 - 调试时加
->asArray():Article::find()->where(['status' => 'published'])->asArray()->all(),避免 ORM 层悄悄丢数据
聚合查询(Aggregation)不能照搬 DSL 写法
扩展封装的聚合接口和原生 Elasticsearch DSL 差异很大,直接套用 JSON 会报错或返回空。它不支持嵌套聚合链、缺少 aggs 外层包装、字段引用方式也不同。
- 不要写
['aggs' => ['by_status' => ['terms' => ['field' => 'status']]]]这种原生结构 - 正确写法是调用方法链:
Article::find()->addAggregation('by_status', ['terms' => ['field' => 'status.keyword']])->search() - 注意字段后缀:ES 7.x/8.x text 字段默认带
.keyword子字段,聚合必须用这个,否则返回空桶
复杂点在于:ES 的 mapping 是一次性的,改字段类型只能删 index 重建;而 Yii 的 ActiveRecord 对字段类型极其敏感,稍有不匹配就静默失效——这点比数据库 ORM 严苛得多,但恰恰是搜索服务稳定性的关键防线。











