Thinkphp5使用Elasticsearch7.0(或以上)

Elastic 7.0以上的版本跟6.0的版本差距非常大,主要是没有type了,网上很多都是老版本的教程。导致我走了很多弯路。

一、使用composer安装Elasticsearch

composer require elasticsearch/elasticsearch

二、新建一个文件ElasticSearch.php



namespace app\common\library;

use Elasticsearch\ClientBuilder;
use think\Config;
use think\Exception;

/**
 * ES专用操作类
 */
class ElasticSearch
{

    private $_host;
    private $_client = null;
    private $_index_prefix = '';
    private $error = '';


    public function __construct()
    {
        $this->setHost();
        $this->_client = ClientBuilder::create()->setHosts($this->_host)->build();
        $this->_index_prefix = \app\common\library\Help::getEnvDiffPrefix();
    }

    /**
     * 设置配置
     */
    private function setHost()
    {
        //实例化一个客户端
        $cfg = Config::get('eshosts');
        $this->_host = [
            $cfg[0]['scheme'] . '://' . $cfg[0]['user'] . ':' . $cfg[0]['pass'] . '@' . $cfg[0]['host'] . ':' . $cfg[0]['port']
        ];
    }

    /**
     * 创建索引
     * @param string $index 文档名称
     * @param array $body 文档主体内容(数组)
     * @return mixed
     */
    public function createIndex($index ='test', $body=[])
    {
        $params = [
            'index' => $this->_index_prefix . $index, //索引名称
            'body' => [
                'settings' => [ //配置
                    'number_of_shards' => 3, //主分片数
                    'number_of_replicas' => 1 //主分片的副本数
                ],
                'mappings' => [  //映射                   
                    '_source' => [   //  存储原始文档
                        'enabled' => 'true'
                    ],
                    'properties' => [ //配置数据结构与类型
                        'title' => [ //字段1
                            'type' => 'text', //类型 text、integer、float、double、boolean、date
                            'index' => 'true', //是否索引
                            'analyzer' => 'ik_max_word' //使用中文IK分词器
                        ]
                    ]

                ],
            ]
        ];
        $this->_client->indices()->create($params);
    }

    public function add_doc($index, $id, $body)
    {
        $index = $this->_index_prefix . $index;
        try {
            $data = [
                'index' => $index,
                'body' => $body,
                'id' => $id
            ];
            $this->_client->index($data);
        } catch (Exception $e) {
            $this->error = $e->getMessage();
            return false;
        }

        return true;
    }

    /**
     * 更新索引
     * @param string $index 文档名称
     * @param string|int $id 文档ID
     * @param array $body 文档主体内容(数组)
     * @param string $type 文档类型(默认为doc)
     * @return bool
     */
    public function updateIndex($index, $id, $body)
    {

        $chk = $this->checkParams($index, $id, $body);
        if ($chk === false) {
            return false;
        }
        $index = $this->_index_prefix . $index;

        try {
            $data = [
                'index' => $index,
                'id' => $id,
                'body' => [
                    'doc' => $body
                ]
            ];
            $this->_client->update($data);
        } catch (Exception $e) {
            $this->error = $e->getMessage();
            return false;
        }

        return true;
    }

    /**
     * 检测索引是否存在,只能单个索引名称检测
     * @param string $index 索引名称
     * @return bool
     */
    public function indexExists($index)
    {

        $response = $this->_client->indices()->exists(['index' => $index]);
        return $response;
    }

    /**
     * 获取索引
     * @param string $index 文档名称
     * @param string|int $id 文档ID
     * @param string $type 文档类型(默认为doc)
     * @return mixed
     */
    public function getIndex($index, $id)
    {
        $index = $this->_index_prefix . $index;
        try {
            $params = [
                'index' => $index,
                'id' => $id
            ];
            $response = $this->_client->get($params);
            return $response['_source'];
        } catch (Exception $e) {
            $this->error = $e->getMessage();
            return false;
        }
    }



    /**
     * 获取索引文档数据列表
     * @param array $params 参数数组集合
     * @param string $type 文档类型(默认为doc)
     * @return mixed
     */
    public function getList($index, $keywords, $limit = 10, $page = 1)
    {
        $offset = ((int)$page - 1) * (int)$limit;
        $params = [
            'index' => $this->_index_prefix . $index,
            'body' => [
                'query' => [
                    'match' => [
                        'title' => $keywords
                    ]
                ],
                'sort' => [['id' => ['order' => 'desc']]],
                'from' => $offset,
                'size' => $limit
            ]
        ];
        $response = $this->_client->search($params);

        //$response['hits']['hits']是具体的数据列表
        return $response;
    }

    /**
     * 删除文档(删除数据记录)
     * @param string $index 文档名称
     * @param string|int $id 文档ID
     * @param string $type 文档类型(默认为doc)
     * @return bool
     */
    public function delDoc($index, $id)
    {
        $chk = $this->checkParams($index, $id, ['def_key' => 'only_for_delete_doc']); //参数3无实际意义,仅用过能通过验证而已
        if ($chk === false) {
            return false;
        }
        $index = $this->_index_prefix . $index;

        try {
            $data = [
                'index' => $index,
                'id' => $id
            ];
            $this->_client->delete($data);
        } catch (Exception $e) {
            $this->error = $e->getMessage();
            return false;
        }

        return true;
    }

    /**
     * 删除索引(相当于删除表)
     * @param string $index 文档名称
     * @return bool
     */
    public function delIndex($index)
    {
        $chk = $this->checkParams($index, '10000', ['def_key' => 'only_for_delete_doc']); //参数2,3无实际意义,仅用过能通过验证而已
        if ($chk === false) {
            return false;
        }
        $index = $this->_index_prefix . $index;

        try {
            $data = [
                'index' => $index
            ];
            $this->_client->indices()->delete($data);
        } catch (Exception $e) {
            $this->error = $e->getMessage();
            return false;
        }

        return true;
    }

    /**
     * 获取ES操作实例
     */
    public function getInstance()
    {
        if (!$this->_client) {
            $this->setHost();
            $this->_client = ClientBuilder::create()->setHosts($this->_host)->build();
        }
        return $this->_client;
    }

    /**
     * 获取索引前缀
     */
    public function getIndexPrefix()
    {
        return $this->_index_prefix;
    }

    /**
     * 参数验证
     * @param string $index 索引文档的名称
     * @param string|int $id 索引文档的ID
     * @param array $body 主体内容
     * @return bool
     */
    private function checkParams($index, $id, $body)
    {
        // if (empty($index) || !is_string($index)) {
        //     $this->error = '必须正确输入索引文档的名称';
        //     return false;
        // }
        // if (empty($id) || !is_string($id) || !is_numeric($id)) {
        //     $this->error = '必须正确输入索引文档的ID';
        //     return false;
        // }
        // if (empty($body) || !is_array($body)) {
        //     $this->error = '必须正确输入索引文档的主体内容';
        //     return false;
        // }
        $result = true;
        foreach ($body as $key => $value) {
            if (!isset($key) || empty($key)) {
                $result = false;
                break;
            }
        }
        if ($result === false) {
            $this->error = '索引文档的主体内容输入不正确';
            return false;
        }
        return true;
    }

    /**
     *返回异常信息
     */
    public function getError()
    {
        return $this->error;
    }
}

三、封号号ES类后,新建一个Index.php文件测试



namespace app\api\controller;

use app\common\library\ElasticSearch; //根据自己路径来引入




/**
 * 测试接口
 */
class Index 
{
    
    protected $_es = null;

    public function __construct()
    {
        $this->_es = new ElasticSearch();
    }

    public function create()
    {
        $this->_es->createIndex('test');
    }

    public function add()
    {
        $id = 1;
        $data = [
            'id' => $id,
            'title' => '我爱天安门',
        ];
        $this->_es->add_doc('test', $id, $data);
    }

    public function search()
    {
        $data = $this->_es->getList('test', '天安门');
        dump($data);
    }

    public function del()
    {
         $this->_es->delIndex('test');
    }
}

完成。

你可能感兴趣的:(PHP,ThinkPHP5.1,php,elasticsearch)