Laravel不使用第三方扩展查询Elasticsearch数据,及通过highlight参数找出匹配到的关键词

语法资料:Link

1、通过第三方扩展

1.1 es数据库不存在数据,需要本地Mysql数据库同步

//可以不指定包版本,但是可能不兼容报错,参考官方Scout文档
composer require laravel/scout=7.1
composer require tamayo/laravel-scout-elastic=5.0
composer require guzzlehttp/guzzle

1.2 es已有数据,只是调用数据

https://github.com/elastic/elasticsearch-php  //官方专门给php提供的api

https://github.com/mmanos/laravel-search
composer require mmanos/laravel-search dev-master

https://github.com/elastic/elasticsearch-php/    //一定要安装和es对应的版本,否则会有问题。
composer require elasticsearch/elasticsearch
composer require "elasticsearch/elasticsearch:~7.4"  //当前最新 7.4
参考:https://www.elastic.co/guide/cn/elasticsearch/php/current/_quickstart.html

https://github.com/elasticquent/Elasticquent

 

2、直接访问es的Api

2.1 curl方式请求

查询索引的具体记录信息
curl 'http://192.168.3.23:9200/news?pretty'
查询指定值的字段是否存在
curl 'http://192.168.3.23:9200/news/_search?pretty&q=link:justice'

2.2 代码层面发起http请求

2.2.1 控制器添加初始化es连接服务

public $client = null;
public function __construct() {
        try {
            $hosts = config('elasticsearch.hosts');
//            $hosts = [
//                '192.168.3.23:9200',
//            ];
            $this->client = ClientBuilder::create()
//            ->setSSLVerification(false)
//            ->setRetries(2)  //重试次数
                ->setHosts($hosts)
                ->build();

            $response = $this->client->info();
            Log::info('Elasticsearch连接成功!'.PHP_EOL);
        } catch (\Exception $e) {
            Log::info('Elasticsearch连接失败!error:'.$e->getMessage().PHP_EOL);
//            return 'error: ' . $e->getMessage();
        }
    }

2.2.2 发起请求

        $indexName = 'news';  //es的索引名
        $url=config('scout.elasticsearch.hosts')[0]."/{$indexName}/_search?";
        $params=[
//            'size' => 10,  //查询最大条数,默认10
            "_source"=> "id,title,link,content,detail,date",  //查询指定字段
            'source'=>json_encode([
//                'explain'=>true,                 //计算查询花费的值
                'query' => [
                    'multi_match' => [
                        'query' => $newkeywords,   //搜索关键词
//                       'type' => '',
                       'fields' => ['title', 'link', 'detail', 'content'] //关键词匹配的字段
                    ]
                ],
//                'highlight' => [      //将匹配到的内容高亮显示
//                    'fields' => [
//                        'test' => {}  // 会报错
//                        'title'=>new \stdClass(),  //由于json_encode([])为[],而非{},所以需要对象
//                        'link'=>new \stdClass(),
//                        'detail'=>new \stdClass(),
//                        'content'=>new \stdClass()
//                    ]
//                ]
            ]),
            'source_content_type'=>'application/json',
        ];

        $search=json_decode(file_get_contents($url.http_build_query($params)),true);
        $search = array_column($search['hits']['hits'], '_source');
        //数组转对象
//        $search = json_decode(json_encode( (object)$search ));  // or
        $search = json_decode(json_encode ( $search, JSON_FORCE_OBJECT ));

打印的结果:

 

3、从highlight里,通过正找出匹配到的关键词,并取出来。

preg_match_all ("/<em>(.*)<\/em>/U", $highlight_keywords_str, $pat_array);
$jeywords = $pat_array[1];
        search_list = [];
        foreach ($search['hits']['hits'] as $key=>$value){
            $search_list[$key] = $value["_source"];
            $highlight_keywords_str = '';
            foreach ($value["highlight"] as $highlight_arr){
                $highlight_str = implode('-', $highlight_arr);
                $highlight_keywords_str = $highlight_keywords_str.'-'.$highlight_str;
            }
            preg_match_all ("/<em>(.*)<\/em>/U", $highlight_keywords_str, $pat_array);
            $search_list[$key]['keywords'] = implode(' ', array_unique(array_map('strtolower', $pat_array[1])));
            $search_list[$key]['highlight'] = $value["highlight"];
        }
        $search = json_decode(json_encode ( $search_list, JSON_FORCE_OBJECT ));


// 有时highlight会遇到<em></em>截了一般的标签,所以就需要strip_tags()处理一下去掉html标签
$search_list[$key]['keywords'] = implode(' ', array_unique(array_map('strip_tags', array_map('strtolower', $pat_array[1]))));

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章