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 AppServicesAbstract; use Exception; use ElasticsearchClientBuilder; 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 AppScripts; use AppServicesAbstractElasticsearchAbstract; use Exception; use IlluminateSupportFacadesDB; use AppModelsDictionary; 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的入门,多看官方文档