laravel8實現ES搜尋

dudukuan發表於2022-03-13

kibana簡介

Kibana是一個與Elasticsearch協同工作的開源分析和視覺化平臺,Kibana 可以讓你更方便地對 Elasticsearch 中資料進行操作,包括高階的資料分析以及在圖表中視覺化您的資料。

ElasticSearch簡介

Elasticsearch一款基於Apache Lucene™開源搜尋引擎,其核心是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫Lucene。Elasticsearch使用簡單,具有非常強大的全文搜尋功能

  • 分散式的實時檔案儲存,每個欄位都被索引並可被搜尋
  • 分散式的實時分析搜尋引擎
  • 可以擴充套件到上百臺伺服器,處理PB級結構化或非結構化資料

ElasticSearch中使用到的概念

  • 叢集(Cluster)

      為所有資料提供儲存和檢索等服務的結點(伺服器)集合。預設的名字為“elasticsearch”,結點(伺服器)也依據名字被指定要加入哪個叢集。
  • 結點(Node)

      作為叢集的一部分,為資料提供儲存和檢索服務的一臺伺服器。
  • 索引(Index)

      索引的概念類似於關聯式資料庫中的資料庫,是相關文件儲存的地方。相應的,“索引一個文件”表示把一個文件儲存在某個索引中
  • 型別(Type)

      索引中文件的邏輯分類,類似於關聯式資料庫中的表。
  • 文件(Document)

      條完整的記錄,類似於關聯式資料庫中的元組。
  • 倒排索引

      Elasticsearch會為文件中的每個欄位都建立倒排索引,這是它實現高效搜尋的基礎之一。

    如有不懂請點選

使用前安裝(如果有就不需要安裝)

1、下載ES與Kibana 移步 下載 kibana 產品 ES下載
2、下載ik分詞器 移步 Releases · medcl/elasticsearch-analysis-ik · GitHub
3、ES KIBANA IK 分詞器下載的版本要一致 如 ES使用6.5.3 kibana也要6.5.3 ik分詞也要6.5.3

一 : 開啟本地的elasticsearch和kibana環境]



雙擊開啟本地的elasticsearch和kibana環境

二 : 在框架內下載composer外掛

composer require elasticsearch/elasticsearch

三 : 使用命令建立elasticsearch的控制器(這邊可自己修改控制器名)

php artisan make:controller Api/esasticSearchController

四 : 在控制器內的名稱空間下呼叫

use Elasticsearch\ClientBuilder;

五 : 新增索引的方法

    /**
     *  新增索引
     * @return string
     */
    public function createDatabase()
    {
        //本地呼叫例項化
         $client  = ClientBuilder::create()->setHosts(['127.0.0.1:9200'])->build();
        //建立索引
        $params = [
            'index' => 'goods',//資料庫名 更換成你自己所建立的索引
            'body' => [
                'settings' => [
                    'number_of_shards' => 5,//建立後可以更改
                    'number_of_replicas' => 1//建立後不可以更改
                ],
                'mappings' => [
                    '_doc' => [
                        '_source' => [
                            'enabled' => true
                        ],
                        'properties' => [
                            //搜尋的欄位名
                            'title' => [
                                'type' => 'text',
                                'analyzer' => 'ik_max_word',//ik分詞器
                                'search_analyzer' => 'ik_max_word'
                            ]
                        ]
                    ]
                ]
            ]
        ];

        //將索引新增到kibana中
        $response = $client->indices()->create($params);

        //判斷結果
        if($response){

            //執行成功
            return "索引新增成功";

        }else{

            //執行失敗
            return "索引新增失敗";
        }
    }

六 : 將資料新增到kibana中

    /**
     *  新增資料到kibana中
     * @return string
     */
    public function createData()
    {
        //本地呼叫例項化
        $hosts = [
            '127.0.0.1:9200'
        ];
        //請求連線
        $client = ClientBuilder::create()->setHosts($hosts)->build();
        //查詢資料表所有的資料並轉化陣列格式
        $date = ApiTitle::all()->toArray();
        //迴圈
        foreach ($date as $v)
        {
            $data = [
                'index' => 'goods',//更改索引名(資料庫名) 其餘不變
                'type' => '_doc',
                'id' => $v['id'],
                'body' => $v,
            ];
            $response = $client->index($data);
        }
        //判斷 是否新增資料成功
        if($response){

            return "新增資料成功";
        }else{

            return "新增資料失敗";
        }
    }

七 : 建立需要搜尋文章的控制器

php artisan make:controller Api/TitleController

八 : 搜尋的方法

    /**
     *  執行搜尋
     * @param Request $request
     */
    public function search(Request $request)
    {
        //接值
        $word = $request->get('title');
        if (!$word){
            return ['code' => 500,'msg' => '未檢測到值','data' => ''];
        }
        //請求連線
        $client = ClientBuilder::create()->build();
        //搜尋的值和庫中的值進行對比
        $params = [
            'index' => 'goods',//資料庫名 更換成你自己所建立的索引
            'type' => '_doc',
            'body' => [
                'query' => [
                    'match' => [
                        //要搜尋的欄位 替換成你自己所要查詢額標籤
                        'title' => $word//要搜尋的內容
                    ]
                ],
                'highlight' => [
                    'pre_tags' => ["<em style='color: #ff0000'>"],//樣式
                    'post_tags' => ["</em>"],
                    'fields' => [
                        //要搜尋的欄位 替換成你自己所要查詢額標籤
                        "title" => new \stdClass()
                    ]
                ]
            ],
        ];
        //執行搜尋
        $results = $client->search($params);
        //迴圈取出值
        foreach ($results['hits']['hits'] as &$v){
        //title這裡的是需要替換成你自己要查詢的標籤
            $v['_source']['title'] = $v['highlight']['title'][0];
        }
        //替換
        $response =array_column($results['hits']['hits'],'_source');
        //返回
        return ['code' => 200,'msg' => '請求成功','data' => $response];
    }

PS:如果在微信小程式中使用的話是直接將標籤和值一起輸出到頁面的,需要加入解析富文字的標籤才可以將標籤轉化格式

  <rich-text nodes="{{item.title}}"></rich-text>

封裝後的ES

在方法中執行
laravel8實現ES搜尋

封裝好的ES檔案

<?php

namespace App\Month\ES;

use Elasticsearch\ClientBuilder;
use Illuminate\Http\Request;

class Es
{
    /**
     * 本地呼叫例項化 預設是9200
     * @param string $hosts
     * 索引名稱(相當於資料庫名)
     * @param $index
     * @return string
     */
    public function createDatabase($index)
    {

        $client  = ClientBuilder::create()->setHosts(["127.0.0.1:9201"])->build();
        //判斷該索引是否存在 如果有則提示有該索引了
        if ($client->indices()->exists(['index'=>$index])){
            return "該索引已經存在";
        }
        //沒有則執行新增
        //建立索引
        $params = [
            'index' => $index,//資料庫名 更換成你自己所建立的索引
            'body' => [
                'settings' => [
                    'number_of_shards' => 5,//建立後可以更改 主分片數
                    'number_of_replicas' => 1//建立後不可以更改 主分片的副本數
                ],
                'mappings' => [
                    '_doc' => [
                        '_source' => [
                            'enabled' => true
                        ],
                        'properties' => [
                            //搜尋的欄位名
                            'title' => [
                                'type' => 'text',
                                'analyzer' => 'ik_max_word',//ik分詞器
                                'search_analyzer' => 'ik_max_word'
                            ]
                        ]
                    ]
                ]
            ]
        ];

        //將索引新增到kibana中
        $response = $client->indices()->create($params);
        //判斷結果
        if($response){

            //執行成功
            return "索引新增成功";

        }else{

            //執行失敗
            return "索引新增失敗";
        }
    }
    /**
     * 例項化 預設是9200
     * @param string $hosts
     * 索引名稱(相當於資料庫名)
     * @param $index
     * 新增資料到kibana中
     * @param $date
     * @return string
     */
    public function createData($index,$date)
    {
        //本地呼叫例項化
        $hosts = [
            "127.0.0.1:9201"
        ];
        //請求連線
        $client = ClientBuilder::create()->setHosts($hosts)->build();
        //迴圈
        foreach ($date as $v)
        {
            $data = [
                'index' => $index,//更改索引名(資料庫名) 其餘不變
                'type' => '_doc',
                'id' => $v['id'],
                'body' => $v,
            ];
            $response = $client->index($data);
        }
        //判斷 是否新增資料成功
        if($response){

            return "新增資料成功";
        }else{

            return "新增資料失敗";
        }
    }
    /**
     * 要搜尋的值
     * @param $word
     * 索引名稱(相當於資料庫名)
     * @param $index
     * 查詢的資料
     * @param $date
     * 根據哪個欄位所查詢
     * @param $title
     * 執行搜尋
     * @param Request $request
     * @return array
     */
    public function search($word,$index,$date,$title)
    {
        if (!empty($word)){
            //請求連線
            $client = ClientBuilder::create()->build();
            //搜尋的值和庫中的值進行對比
            $params = [
                'index' => $index,//資料庫名 更換成你自己所建立的索引
                'type' => '_doc',
                'body' => [
                    'query' => [
                        'match' => [
                            //要搜尋的欄位 替換成你自己所要查詢額標籤
                            $title => $word//要搜尋的內容
                        ]
                    ],
                    'highlight' => [
                        'pre_tags' => ["<em style='color: #ff0000'>"],//樣式
                        'post_tags' => ["</em>"],
                        'fields' => [
                            //要搜尋的欄位 替換成你自己所要查詢額標籤
                            $title => new \stdClass()
                        ]
                    ]
                ],
            ];
            //執行搜尋
            $results = $client->search($params);
            //迴圈取出值
            foreach ($results['hits']['hits'] as &$v){
                //title這裡的是需要替換成你自己要查詢的標籤
                $v['_source']["$title"] = $v['highlight']["$title"][0];
            }
            //替換
            $date =array_column($results['hits']['hits'],'_source');
        }
        //返回
        return $date;
    }

}

修改ES的訪問路徑(注意也得把kibana裡面ES的路由進行修改,下方也放置了相對應的圖片):
修改ES的路由:
laravel8實現ES搜尋

laravel8實現ES搜尋
修改kibana裡面的ES的URL路徑:
laravel8實現ES搜尋

(我這裡是用的6.53版本的,如果是其他版本可能會出現版本錯誤,如有錯誤請聯絡博主)

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章