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]))));

 

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