0%

laravel&es

由于最近需求有要用到ES,所以重新熟悉一下PHP和ES之间的调用。
PHP框架:laravel 7.29
ES:7.11.2
Kibana:7.11.2

ES下载后运行bin目录下的elasticsearch可执行文件。

思路:用 scout 做 es 和 mysql 的同步,初步也使用scout做搜索请求,如果有复杂的搜索条件则单独用es原生PHP包。

初始化laravel框架并安装所需库:

1
2
3
4
5
6
7
8
9
10
sudo /Applications/MAMP/bin/php/php7.2.22/bin/php /usr/local/bin/composer create-project laravel/laravel learnes

php composer require laravel/scout=v8.6.0 -vvv
php composer require elasticsearch/elasticsearch=7.11.0 -vvv
php composer require tamayo/laravel-scout-elastic=8.0.2 -vvv
php composer require ongr/elasticsearch-dsl=v7.2.1 -vvv

按照scout文档初始化scout扩展 https://learnku.com/docs/laravel/8.x/scout/9422
生成配置文件 config/scout.php
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

然后在 .env 增加配置:
SCOUT_DRIVER=elasticsearch

然后在 config/scout.php 增加ES的配置:
‘elasticsearch’ => [
‘index’ => env(‘ELASTICSEARCH_INDEX’, ‘estest’),//索引名称
‘hosts’ => [
env(‘ELASTICSEARCH_HOST’, ‘http://127.0.0.1:9200'),
],
],

在 mysql 建立一个数据库,建立一张posts表,有title、author、body、created_at、updated_at 字段。

建立model,并按照scout文档所述,添加trait以保持Model对数据的操作与搜索驱动索引的同步。
索引index名称默认为model名称全小写,对于Posts来说,索引名称就是posts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Posts extends Model
{
use Searchable;
protected $primaryKey = 'id';
public $timestamps = true;
protected $guarded = [];

/**
* 设置导入索引的数据字段
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();

// 自定义数组...

return $array;
}
}

// 向数据库写入数据,并自动同步到索引

1
2
3
4
5
6
7
for ($i=1; $i <= 20; $i++) { 
Posts::create([
'title' => 'test' . $i,
'author' => 'author' . $i,
'body' => 'body' . $i
]);
}

// 根据条件清除索引数据,但不清除数据库数据

1
Posts::where('id', '!=', -1)->unsearchable();

// 更新并同步到索引

1
2
3
4
5
$post = Posts::where('id', 82)->first();
$post->title = 'test_update';
$post->author = 'author_update';
$post->body = 'body_update';
$post->save();

// 命令行清空该索引下数据
curl -X DELETE http://localhost:9200/posts

几个命令

1
2
3
4
5
// 导入所有已存在的记录到搜索索引
php artisan scout:import "App\Model\Posts"

// 从搜索索引中删除所有模型的记录
php artisan scout:flush "App\Model\Posts"

// 搜索,由于scout提供的搜索功能很简单,所以复杂查询用es官方提供的php包和一个DSL查询构造器的包组合使用。

若操作ES报错:

1
index [.async-search] blocked by: [TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block];

解决方式:

1
2
3
4
5
curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_cluster/settings -d '{ "transient": { "cluster.routing.allocation.disk.threshold_enabled": false } }'

curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'

参考:https://selleo.com/til/posts/esrgfyxjee-how-to-fix-elasticsearch-forbidden12index-read-only

scout文档:https://learnku.com/docs/laravel/8.x/scout/9422
参考:https://learnku.com/articles/30812
https://learnku.com/articles/48630