ElasticSearch - php操作示例分享

161 阅读1分钟
<?php
/*
 * @Author: psq
 * @Date: 2022-11-16 16:12:54
 * @LastEditors: psq
 * @LastEditTime: 2022-11-18 17:10:42
 */

namespace app\services;

use Elasticsearch\ClientBuilder;

/**
 * @description: ElasticSearch 操作类
 * @return {*}
 */
class ElasticSearch {

    /**
     * @description: 
     * @param {string} $host        Es连接地址
     * @param {string} $port        Es连接端口
     * @param {string} $user        Es连接用户
     * @param {string} $password    Es连接密码
     * @param {string} $password    Es连接方式
     * @return {*}
     */    
    public function __construct(string $host, string $port, string $user = 'elastic', string $password, string $schema = 'http')
    {
        
        $this->elasticsearch = ClientBuilder::create()->setHosts([[
            'host'      =>  $host,
            'port'      =>  $port,
            'schema'    =>  $schema,
            'user'      =>  $user,
            'pass'      =>  $password
        ]])->build();
    }
 
    /**
     * @description: 根据id修改数据行
     * @param {string} $index
     * @param {int} $id
     * @param {array} $body
     * @param {bool} $refresh
     * @return {bool}
     */    
    public function updateDocument(string $index, int $id, array $body, bool $refresh = false) :bool
    {

        try {
            
            $this->elasticsearch->update(['index' => $index,  'id' =>  $id, 'refresh' => $refresh, 'body' =>  ['doc' => $body]]);

            return true;
            
        } catch (\Throwable $e) {
            
            return false;
        }
    }

    /**
     * @description: 根据id查询数据
     * @param {string} $index
     * @param {int} $id
     * @return {array}
     */    
    public function getSource(string $index, int $id) :array
    {

        try {
            
            return $this->elasticsearch->getSource(['index' =>  $index, 'id'    =>  $id]);
            
        } catch (\Throwable $e) {
            
            return [];
        }
    }

    /**
     * @description: 分页获取文档
     * @param {string} $index
     * @param {int} $page
     * @param {int} $pagesige
     * @param {array} $where 传参格式参考如下
     * $where = [
     *      // 多条件匹配,满足其一即可
     *      'should'  =>  [
     *          ['match' => ['name' => '苹果']],
     *          ['match' => ['doc'  => '这个是']]
     *       ],
     *      // 否决条件匹配
     *      'must_not'  =>  [
     *          ['match' => ['name' => '小米']]
     *       ]
     * ]
     * @param {array} $orderby 传参格式参考如下
     * $orderby = [
     *      'add_time'  =>  'desc | asc'
     * ]
     * 
     * @return {array}
     */    
    public function getPageDocument(string $index, int $page, int $pagesize, array $where, array $orderby = []) :array
    {

        $res = [
            'total_count'   =>  0,          // 数据总条数
            'page'          =>  $page,      // 页码
            'page_size'     =>  $pagesize,  // 每页显示条数
            'page_count'    =>  0,          // 分页总数
            'data'          =>  []          // 分页数据
        ];

        try {
            
            $search = [
                'index'             =>  $index,
                'from'              =>  $page <= 1 ? 0 : ($page - 1) * $pagesize,
                'size'              =>  $pagesize,
                'track_total_hits'  =>  true,
                'body'              =>  ['query' => ['bool' => $where]]
            ];

            $data = $this->elasticsearch->search($search);

        } catch (\Throwable $th) {
            
            return $res;
        }

        foreach ($data['hits']['hits'] as $key => $value) 
        {
            $value['_source']['_id'] = $value['_id'];
            array_push($res['data'], $value['_source']);
        }
        
        $res['total_count'] = $data['hits']['total']['value'];
        $res['page_count']  =  (int) ceil($data['hits']['total']['value'] / $pagesize);

        return $res;
    }

    /**
     * @description: 根据id删除数据行
     * @param {string} $index
     * @param {int} $id
     * @return {bool}
     */    
    public function deleteDocument(string $index, int $id) :bool
    {
        
        try {
            
            $this->elasticsearch->delete(['index' => $index, 'id' => $id]);
            
            return true;

        } catch (\Throwable $e) {
            
            return false;
        }

    }

    /**
     * @description:    创建文档 [数据行]
     * @param {string} $index
     * @param {array} $body
     * @param {int} $id
     * @return {bool}
     */    
    public function createDocument(string $index, array $body, int $id) :bool
    {       

        try {
            
            $this->elasticsearch->index(['index' =>  $index, 'body'  =>  $body, 'id'    =>  $id]);

            return true;

        } catch (\Throwable $e) {
            
            return false;
        } 
    }

    /**
     * @description: 获取所有索引
     * @return {*}
     */    
    public function getAllIndex() :array
    {

        return array_keys($this->elasticsearch->indices()->getMapping());
    }

    /**
     * @description: 获取索引映射
     * @param {string} $index
     * @return {array}
     */    
    public function getIndexMap(string $index = '') :array
    {

        try {
            
            return $this->elasticsearch->indices()->getMapping(empty($index) ? [] : ['index' => $index]);

        } catch (\Throwable $e) {
            
            return [];
        }
    }

    /**
     * @description: 获取索引结构
     * @param {string} $index
     * @return {array}
     */    
    public function getIndexSettings(string $index) :array
    {
        try {

            return $this->elasticsearch->indices()->getSettings(['index' => $index]);

        } catch (\Throwable $e) {
            
            return [];
        }
    }

    /**
     * @description: 查询索引是否存在
     * @param {string} $index
     * @return {bool}
     */    
    public function existsIndex(string $index) :bool
    {
        
        return $this->elasticsearch->indices()->exists(['index' => $index]);
    }
    
    /**
     * @description: 创建索引
     * @param {string} $index
     * @param {array} $body
     * @return {bool}
     */    
    public function createIndex(string $index, array $body) :bool 
    {
        try {

            $run = $this->elasticsearch->indices()->create([
                'index'             => $index,
                'include_type_name' =>  true,
                'body'              => [
                    'mappings'          => [
                        'magic'             => [
                            '_source'           => [
                                'enabled'   => true
                            ],
                            'properties'    =>  $body
                        ]
                    ]
                ]
            ]);

            return $run['acknowledged'];            

        } catch (\Throwable $e) {
            
            return false;
        }
    }

    /**
     * @description: 删除索引  !!【谨慎使用,索引删除了数据也没了】
     * @param {string} $index
     * @return {bool}
     */    
    public function deleteIndex(string $index) :bool
    {

        try {

            return $this->elasticsearch->indices()->delete(['index' => $index])['acknowledged'];

        } catch (\Throwable $e) {
            
            return false;
        }
    }
}