php开发技巧

lumen + elasticsearch 索引操作类

2019-08-28  本文已影响0人  顶尖少爷

安装扩展

composer require elasticsearch/elasticsearch

模型

namespace App\Elas\Modules\Article\Model;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    const ARTICLE_INDEX = 'el_ar_zhihu_article';
    const ARTICLE_TYPE = 'el_ar_zhihu_article_type';
}


实现类

namespace App\Elas\Modules\Article\Repositories;

use App\Elas\Modules\Article\Model\Article;
use Elasticsearch\ClientBuilder;
use Elasticsearch\Common\Exceptions\TransportException;
use Log;
class ElasArticleRepository
{

    protected $client;
    protected $pagesize;
    public function __construct()
    {
        $this->pagesize =10;
        $hosts=explode(',',env('ES_HOST','localhost'));
        $defaultHandler = ClientBuilder::defaultHandler();
        $this->client = ClientBuilder::create()->setHosts($hosts)->setRetries(2)->setHandler($defaultHandler)->build();
    }

    /**
     * 索引一个文档
     * @param $id
     * @param $ar_content
     * @param $or_content
     */
    public function insertElastic($id=0,$or_content='',$ar_content='',$p_id=0,$p_name='',$a_id=0,$a_p_id=0,$a_p_name=null,$ar_answer=null){
        $params = [
            'index' => Article::ARTICLE_INDEX,
            //'type' =>Article::ARTICLE_TYPE,
            'id'=>$id,
            'body'=>[
                'id'=>$id,
                'or_content'=>$or_content, //原文内容
                'ar_content'=>$ar_content, //阿语内容
                'p_id'=>$p_id,     //用户id
                'p_name'=>$p_name, //发问用户名
                'a_id'=>$a_id,      //答案id
                'a_p_id'=>$a_p_id   , //点赞次数最多的答案所对应的用户id
                'a_p_name'=>$a_p_name   , //点赞次数最多的答案所对应的用户名
                'ar_answer'=>$ar_answer, //点赞次数最多的答案阿语答案
                "create_at"=>time()
            ]
        ];
        try{
            $this->client->index($params);
            Log::info("ok");
            return true;
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('存储索引失败',['错误信息'=>$previous]);
            return false;
        }
    }


  //更新索引数据
    public function updateElastic($id=0,$or_content='',$ar_content='',$p_id=0,$p_name='',$a_p_id=0,$a_p_name=''){
        $params = [
            'index' => Article::ARTICLE_INDEX,
            //'type' =>Article::ARTICLE_TYPE,
            'id'=>$id,
            'body'=>[
                'doc'=>[
                    'id'=>$id,
                    'or_content'=>$or_content, //原文内容
                    'ar_content'=>$ar_content, //阿语内容
                    'p_id'=>$p_id,     //用户id
                    'p_name'=>$p_name, //发问用户名
                    'a_p_id'=>$a_p_id   , //点赞次数最多的答案所对应的用户id
                    'a_p_name'=>$a_p_name   , //点赞次数最多的答案所对应的用户名
                    "create_at"=>time()
                ]
            ]
        ];
        try{
            $this->client->update($params);
            Log::info("ok");
            return true;
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('存储索引失败',['错误信息'=>$previous]);
            return false;
        }
    }


    /**
     * 根据id精准查找
     * @param $id
     * @return array
     */
    public function findElasticById($id=0){

        $params = [
            'index' => Article::ARTICLE_INDEX,
            //'type' =>Article::ARTICLE_TYPE,
            'id'=>$id,
        ];
        try{
            return $this->client->get($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('查询索引失败',['错误信息'=>$previous]);
            return false;
        }

    }


    /**
     * 分页查询 es
     * @param int $page
     * @return array|bool|callable
     */
    public function getESource($page=0){
        //查询一定存在答案的
        //一定有阿语翻译的
        $match = [
            "bool"=>[
                "must_not"=>[
                    "match"=>["a_id"=> 0],
                ],
                "must"=>[
                    "exists"=>[
                        "field"=> "ar_content",
                    ]
                ]
            ],

        ];
        $params = [
            'size'=>$this->pagesize,
            'index' => Article::ARTICLE_INDEX,
            'body' => [
                'query' =>$match,
            ],
            'sort' => array('create_at:desc'),
            'from'=>$page*$this->pagesize  //用偏移量进行分页
        ];
        try{
            return $this->client->search($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('搜索失败',['错误信息'=>$previous]);
            return false;
        }
    }


    public function getNotAnswerESource(){
        //查询一定不存在答案的
        $match = [
            "bool"=>[
                "must"=>[
                    "match"=>[
                        "a_id"=> 0
                    ]
                ]
            ]
        ];
        $params = [
            'size'=>3,
            'index' => Article::ARTICLE_INDEX,
            'body' => [
                'query' =>$match,
            ],
            'sort' => array('create_at:desc'),
            'from'=>0  //用偏移量进行分页
        ];
        try{
            return $this->client->search($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('搜索失败',['错误信息'=>$previous]);
            return false;
        }
    }




    public function searchElasticByQuery($match,$page=0){
        $params = [
            'size'=>$this->pagesize,
            'index' => Article::ARTICLE_INDEX,
            'body' => [
                'query' =>['match_phrase'=>$match],
            ],
            'sort' => array('create_at:desc'),
            'from'=>$page*$this->pagesize  //用偏移量进行分页


        ];
        try{
            return  $this->client->search($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('搜索失败',['错误信息'=>$previous]);
            return false;
        }
    }


    /**
     * 搜索文档
     * @param $query
     * @return array
     * match_phrase 短语匹配
     */
    public function searchElasticTypePhraseByQuery($match,$page=0){
        $params = [
            'size'=>$this->pagesize,
            'index' => Article::ARTICLE_INDEX,
            'body' => [
                'query' =>['match_phrase'=>$match],
            ],
            'sort' => array('create_at:desc'),
            'from'=>$page*$this->pagesize  //用偏移量进行分页


        ];
        try{
            return  $this->client->search($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('搜索失败',['错误信息'=>$previous]);
            return false;
        }
    }

    /**
     * 通过标签搜索 获取相似
     * @param $match
     * @return array|bool|callable
     */
    public function searchElasticTagPhraseByQuery($id, $match){
        $params = [
            'size'=>3,
            'index' => Article::ARTICLE_INDEX,
            'body' => [
                'query' =>[
                    "bool"=>[
                        "must_not"=>[
                            "match"=>["id"=>$id],
                        ],
                        "must"=>[
                            "nested"=>[
                                "path"=> "tags_v2",
                                "query"=>$match
                            ],
                        ]
                    ],
                ],
            ],
            'sort' => [
                "_score:desc",
                "create_at:desc"
            ],
            //'from'=>0  //用偏移量进行分页
        ];

        try{
            return  $this->client->search($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('搜索失败',['错误信息'=>$previous]);
            return false;
        }
    }

    /**
     * 判断索引是否 存在
     * @param int $id
     * @return bool
     */
    public function checkElasticExists($id=0){
        $params = [
            'index' => Article::ARTICLE_INDEX,
            //'type' =>Article::ARTICLE_TYPE,
            'id'=>$id,
        ];
        try{
            return $this->client->exists($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('查询索引失败',['错误信息'=>$previous]);
            return false;
        }
    }

    /**
     * 删除一个文档
     * @param $id
     * @return array
     */
    public function deleteElasticById($id){
        $params = [
            'index' => Article::ARTICLE_INDEX,
            'type' =>Article::ARTICLE_TYPE,
            'id'=>$id,
        ];
        try{
            $this->client->delete($params);
        }catch (TransportException $e){
            $previous = $e->getPrevious();
            Log::error('删除文档失败',['错误信息'=>$previous]);
            return false;
        }

    }
    /******************************************************************************************************************/
    /**
     * 慎用
     * 删除一个索引
     * @param $index
     * @return array
     */
    public  function deleteIndicesByIndex($index){
        $deleteParams = ['index' => $index];
        return $this->client->indices()->delete($deleteParams);
    }

    /**
     * 创建索引
     * @param $index
     * @return array
     */
    public function createIndices(){

        $params = [
            'index' => Article::ARTICLE_INDEX,
            //'type' => Article::ARTICLE_TYPE,
            'id'=>"0",
            'body' => [
                'settings' => [
                    "number_of_shards"=>3 ,   //设置分片数量
                    "number_of_replicas"=>2,  //设置副本数量
                ],
                'properties'=>[
                    'q_id'=>[
                        'type'=>'integer',
                        'store'=>'yes', //公共属性
                        'precision_step' =>'0'  //指定为该字段生成的词条数,值越低,产生的词条数越多,查询会更快,但索引会更大。默认4
                    ],
                    "or_content"=>[
                        'type'=>'long',
                        'store'=>'yes', //公共属性
                        'boost'=>1, //文档中该字段的重要性,值越大表示越重要,默认1
                        "index"=>"analyzed", //analyzed:编入索引供搜索、no:不编入索引、not_analyzed(string专有):不经分析编入索引
                    ],
                    "ar_content"=>[
                        'type'=>'long',
                        'store'=>'yes', //公共属性
                        'boost'=>1, //文档中该字段的重要性,值越大表示越重要,默认1
                        "index"=>"analyzed", //analyzed:编入索引供搜索、no:不编入索引、not_analyzed(string专有):不经分析编入索引
                    ],
                    "p_id"=>[
                        'type'=>'integer',
                        'store'=>'yes', //公共属性
                        'precision_step' =>'0'  //指定为该字段生成的词条数,值越低,产生的词条数越多,查询会更快,但索引会更大。默认4
                    ],
                    "p_name"=>[
                        'type'=>'string',
                        'store'=>'yes', //公共属性
                        'boost'=>1, //文档中该字段的重要性,值越大表示越重要,默认1
                        "index"=>"analyzed", //analyzed:编入索引供搜索、no:不编入索引、not_analyzed(string专有):不经分析编入索
                    ]
                    "a_p_id"=>[
                        'type'=>'integer',
                        'store'=>'yes', //公共属性
                        'precision_step' =>'0'  //指定为该字段生成的词条数,值越低,产生的词条数越多,查询会更快,但索引会更大。默认4
                    ],
                    "a_p_name"=>[
                        'type'=>'string',
                        'store'=>'yes', //公共属性
                        'boost'=>1, //文档中该字段的重要性,值越大表示越重要,默认1
                        "index"=>"analyzed", //analyzed:编入索引供搜索、no:不编入索引、not_analyzed(string专有):不经分析编入索
                    ]
                ]
            ]
        ];
        return $this->client->create($params);
    }
}


上一篇 下一篇

猜你喜欢

热点阅读