PHP实现elasticsearch/elasticsearchy实例

es中文文档

https://learnku.com/docs/elasticsearch73/7.3

极客时间-Elasticsearch核心技术与实践-课件及 Demo 下载地址

https://gitee.com/geektime-geekbang/geektime-ELK

第一:安装elasticsearch环境
## 相关阅读
- 安装指南 https://www.elastic.co/guide/en/elasticsearch/reference/7.1/install-elasticsearch.html
- Elastic Support Matrix(OS / JDK ) https://www.elastic.co/cn/support/matrix
- Elasticsearch 的一些重要配置 https://www.elastic.co/guide/en/elasticsearch/reference/current/important-settings.html
- https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html
- https://www.elastic.co/guide/en/elasticsearch/reference/current/important-settings.html
- Elasticsearch on Kuvernetes https://www.elastic.co/cn/blog/introducing-elastic-cloud-on-kubernetes-the-elasticsearch-operator-and-beyond
- CAT Plugins API https://www.elastic.co/guide/en/elasticsearch/reference/7.1/cat-plugins.html

window 的使用,首先下载安装包,百度网盘下载(https://pan.baidu.com/s/1CRT3W4wEESglCBDnslk2AA)
解压到本地,我是D:\elasticsearch-7.1.0

#启动单节点 
bin/elasticsearch -E node.name=node0 -E cluster.name=geektime -E path.data=node0_data
window .\bin\elasticsearch

#安装插件
bin/elasticsearch-plugin install analysis-icu
window .\bin\elasticsearch-plugin install analysis-icu
第二:composer require elasticsearch/elasticsearch
第三

单例,InstanceTrait.php

<?php
/**
 * Created by PhpStorm.
 * User: owenzhang
 * Date: 2019/3/4
 * Time: 下午4:30
 */

namespace app\common;

trait InstanceTrait
{
    private static $instances;

    protected function __construct()
    {
    }

    private function __clone()
    {
    }

    /**
     * @return static
     */
    public static function getInstance()
    {
        $className = get_called_class();
        $args = func_get_args();
        //若$args中有resource类型的参数,则无法区分同一个类的不同实例
        $key = md5($className . ':' . serialize($args));
        if (!isset(self::$instances[$key])) {
            //PHP_VERSION >= 5.6.0
            self::$instances[$key] = new $className(...$args);
        }
        return self::$instances[$key];
    }
}

服务,ElasticSearchModel.php

<?php
/**
 * ElasticSearch
 */
namespace app\common\model;

use app\common\InstanceTrait;
use Elasticsearch\ClientBuilder;
use Elasticsearch\Common\Exceptions\Missing404Exception;

class ElasticSearchModel
{
    use InstanceTrait;

    private $_devConfig = [
        'sports_search_expert' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_expert'
        ],
        'sports_search_blog' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_blog'
        ]
    ];

    private $_prodConfig = [
        'sports_search_expert' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_expert'
        ],
        'sports_search_blog' => [
            'host' => '127.0.0.1',
            'port' => 9200,
            'index' => 'sports_search_blog'
        ],
    ];

    private $_config;
    private $_client;
    private $_error = false;

    public function __construct($key)
    {
        $this->_config = $this->_devConfig;
        if (env('APP_ENV') == 'prod') {
            $this->_config = $this->_prodConfig;
        }

        if (!array_key_exists($key, $this->_config)) {
            $this->_error = true;
            return;
        }

        $this->_config = $this->_config[$key];
        $hosts = [$this->_config['host'] . ':' . $this->_config['port']];
        $this->_client = ClientBuilder::create()->setHosts($hosts)->build();
    }

    /**
     * 插入数据
     *
     * data['type']
     * data['data']
     */
    public function addDoc($type, $data)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }
            if (!is_array($data)) {
                throw new \Exception('参数缺失');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'body' => $data,
            ];

            if (isset($data['id'])) {
                $params['id'] = $data['id'];
            }

            $this->_client->index($params);
            return ['code' => 0, 'msg' => '成功'];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => $exception->getMessage()];
        }
    }

    /**
     * 查询数据
     */
    public function getDocById($type, $id)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'id' => $id
            ];
            return ['code' => 0, 'msg' => '成功', 'data' => $this->_client->get($params)];
        } catch (Missing404Exception $exception) {
            return ['code' => 0, 'data' => []];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => $exception->getMessage()];
        }
    }

    /**
     * 根据ID更新数据
     */
    public function updateDoc($type, $id, $data)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'id' => $id,
                'body' => ['doc' => $data]
            ];

            return ['code' => 0, 'msg' => '成功', 'data' => $this->_client->update($params)];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => $exception->getMessage()];
        }
    }

    /**
     * 搜索
     */
    public function searchDoc($type, $body, $page = 1, $size = 10)
    {
        try {
            if ($this->_error) {
                throw new \Exception('配置错误');
            }

            $params = [
                'index' => $this->_config['index'],
                'type' => $type,
                'body' => $body,
                'from' => ($page - 1) * $size,
                'size' => $size
            ];

            $data = $this->_client->search($params);
            $hits = isset($data['hits']) ? $data['hits'] : [];
            $total = isset($hits['total']) ? $hits['total'] : 0;
            $hitsArr = isset($hits['hits']) ? $hits['hits'] : [];
            $list = [];
            foreach ($hitsArr as $value) {
                $list[] = $value['_source'];
            }

            $return = [
                'total' => $total,
                'list' => $list
            ];
            return ['code' => 0, 'msg' => '成功', 'data' => $return];
        } catch (\Exception $exception) {
            \Log::error($exception);
            return ['code' => -1, 'msg' => '暂无数据', 'data' => []];
        }
    }
}

实例:SyncBlog.php

添加,更新,获取一个

ElasticSearchModel::getInstance('sports_search_blog')->addDoc('blog', $data);

ElasticSearchModel::getInstance('sports_search_blog')->updateDoc('blog', $id, $data);

ElasticSearchModel::getInstance('sports_search_blog')->getDocById('blog', $id);

<?php
/**
 * 同步资讯
 */

namespace app\polymerize\tool\module\es;

use app\common\model\BlogModel;
use app\common\model\ElasticSearchModel;

class SyncBlog
{
    use \app\common\InstanceTrait;

    public function syncBlog($id)
    {
        //获取用户数据
        $blogInfo = BlogModel::getInstance()->getOneById($id, 4, 'sports');
        if (empty($blogInfo)) {
            return ['code' => -1, 'msg' => '不存在该资讯'];
        }

        //判断是否存在
        $result = ElasticSearchModel::getInstance('sports_search_blog')->getDocById('blog', $id);
        if (!empty($result['code'])) {
            return $result;
        }

        //不存在写入
        if (empty($result['data'])) {
            $data = [
                'id' => $id,
                'search' => $blogInfo['title'],
                'status' => $blogInfo['status']
            ];
            ElasticSearchModel::getInstance('sports_search_blog')->addDoc('blog', $data);
            return $result;
        }

        //存在更新
        $data = [
            'search' => $blogInfo['title'],
            'status' => $blogInfo['status']
        ];
        $result = ElasticSearchModel::getInstance('sports_search_blog')->updateDoc('blog', $id, $data);
        return $result;
    }
}

分页查找

ElasticSearchModel::getInstance('sports_search_blog')->searchDoc('blog', $data, $pageNo, $pageCount);

SearchBlog.php

<?php
/**
 * 搜索资讯
 */
namespace app\polymerize\tool\module\es;

use app\common\InstanceTrait;
use app\common\model\BlogModel;
use app\common\model\ElasticSearchModel;

class SearchBlog
{
    use InstanceTrait;

    public function searchBlog($name, $pageNo, $pageCount)
    {
        $data = [
            'query' => [
                'bool' => [
                    'must' => [
                        'match' => [
                            'search' => $name
                        ]
                    ],
                    'filter' => [
                        'term' => [
                            'status' => 1 //TODO 改成常量
                        ]
                    ],
                ],
            ]
        ];
        $result = ElasticSearchModel::getInstance('sports_search_blog')->searchDoc('blog', $data, $pageNo, $pageCount);

        if ($result['code'] != 0 || empty($result['data'])) {
            return $result;
        }

        $data = $result['data'];
        $list = $data['list'];

        $blogIdArr = array_column($list, 'id');
        $blogInfo = BlogModel::getInstance()->getBlogListByIdArrAndTypeIdArr($blogIdArr);

        $return = [];
        foreach ($list as $value) {
            if (!isset($blogInfo[$value['id']])) {
                continue;
            }

            $return[] = [
                'blog_id' => $value['id'],
                'blog_title' => $blogInfo[$value['id']]['title'],
                'blog_img' => $blogInfo[$value['id']]['thumbnail_url'],
            ];
        }

        $return = [
            'list' => $return,
        ];

        return ['code' => 0, 'data' => $return];
    }
}

Buy me a cup of coffee :)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值