php调用Elasticsearch

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的入门,多看官方文档

 

QQ一群 247823727 (满了)
QQ二群 166427999 (新群,写PHP最佳实践为主)
博客文件如果不能下载请进群下载
如果公司项目有技术瓶颈问题,如有需要,技术服务QQ: 903464207

posted on 2021-09-16 16:37  zh7314  阅读(38)  评论(0编辑  收藏  举报