2021年9月13日16:11:09
PHP版本8,laravel8 elasticsearch 7.14.0
本地虚拟机的centos7.9 openjdk java 1.8
composer require elasticsearch/elasticsearch
目前已经支持 php: ^7.3 || ^8.0
需要简单封装下
<?php
namespace App\Services\Abstract;
use Exception;
use Elasticsearch\ClientBuilder;
abstract class ElasticsearchAbstract
{
protected static $client = null;
/*
* 所有的index,都要写index的创建参数,避免结构丢失
*
* 异常捕捉去调用脚本的最外层捕捉
*/
abstract public static function buildIndex();
//配置参数
abstract public static function indexParams();
public static function getClient()
{
if (self::$client == null) {
$config = env('ES_CONFIG', '192.168.154.131:9200');
if (empty($config)) {
throw new Exception('elasticsearch配置不能为空');
}
$config = explode(',', $config);
self::$client = ClientBuilder::create()->setHosts($config)->build();
return self::$client;
} else {
return self::$client;
}
}
}
其他的索引操作就直接集成这个抽象类
<?php
namespace App\Scripts;
use App\Services\Abstract\ElasticsearchAbstract;
use Exception;
use Illuminate\Support\Facades\DB;
use App\Models\Dictionary;
class MedicineDictionaryScript extends ElasticsearchAbstract
{
public static function buildIndex()
{
$client = parent::getClient();
$params = self::indexParams();
$response = $client->indices()->create($params);
if ($response['acknowledged'] != 1) {
throw new Exception('索引创建失败');
}
return $response;
}
public static function indexParams()
{
return [
'index' => 'his_tabls_index',
'body' => [
'settings' => [
'number_of_shards' => 3,
'number_of_replicas' => 3
],
'mappings' => [
'_source' => [
'enabled' => true
],
'properties' => [
'id' => [
'type' => 'integer'
],
'name' => [
'type' => 'text',
'analyzer' => 'ik_smart',
'search_analyzer' => 'ik_smart'
],
'type' => [
'type' => 'keyword',
],
'description' => [
'type' => 'text',
'analyzer' => 'ik_smart',
'search_analyzer' => 'ik_smart'
]
]
]
]
];
}
public static function generateDataToEs()
{
// ini_set('memory_limit', '1024M');
$client = parent::getClient();
if (Dictionary::count() > 0) {
Dictionary::select(['id', 'name', 'type', 'description'])->where('is_delete', 10)->chunkById(1000, function ($list) use ($client) {
foreach ($list as $k => $v) {
pp($v->toArray());
$params = [
'index' => 'his_tabls_index',
'body' => $v->toArray()
];
$client->index($params);
}
});
}
}
}
注意:官方文档最好看英文的,中文的版本比较落后,DSL很多操作,都有变化,比如现在已经不再支持type类型了
索引我压入了145w条数据
格式如下
{
"_index": "his_tabls_index",
"_type": "_doc",
"_id": "trj87nsBAYl3v0SNIW7Q",
"_version": 1,
"_score": null,
"_source": {
"id": 1452979,
"name": "牛黄清心丸",
"type": "中药",
"description": "中医药相关词汇"
},
"sort": [
1452979
]
}
查询结果
GET /his_tabls_index/_search
{
"query": {
"match": {
"description":{
"query": "中医西医",
"analyzer": "ik_max_word"
}
}
},
"size": 10
}
第一次返回50ms左右,第二有缓存之后10ms,性能很好
想说的一点建议:
1,es的集群效果更好
2,如果需要指定分词器,或者指定评分,需要很熟悉
3,mysql聚合的操作,基本都可以在es实现,但是看官方文档一点一点聚合
4,因为是类似文档数据库,所以以前的习惯会影响你对es的入门,多看官方文档