ELASTIC-PHP + IK分詞器 + THINKPHP6 初次使用 (關鍵詞查詢)
阿新 • • 發佈:2020-08-06
環境:centos 6 php73 mysql56 ELASTIC7.71
1.安裝elastic 使用華為雲映象更快哦https://mirrors.huaweicloud.com/elasticsearch/
wget https://mirrors.huaweicloud.com/elasticsearch/7.7.1/elasticsearch-7.7.1-linux-x86_64.tar.gz tar -zxvf elasticsearch-7.7.1-linux-x86_64.tar.gz
2.新增使用者(使用者啟動elastic 不能用root所以) 去目錄裡面編輯配置 elastic.yml
groupadd elastic useradd -g elastic elastic chown -R elastic.elastic /etc/elasticsearch-7.7.1 vim config/elasticsearch.yml
配置如下 注意冒號後有空格
------------------------------------ Node ------------------------------------ # # Use a descriptive name for the node: # node.name: hxx-node-1 # # Add custom attributes to the node: # #node.attr.rack: r1 # # ----------------------------------- Paths ------------------------------------ # # Path to directory where to store the data (separate multiple locations by comma): # path.data: /var/elastic/data # # Path to log files: # path.logs: /var/elastic/logs # # ----------------------------------- Memory ----------------------------------- # # Lock the memory on startup: # #bootstrap.memory_lock: true # # Make sure that the heap size is set to about half the memory available # on the system and that the owner of the process is allowed to use this # limit. # # Elasticsearch performs poorly when the system is swapping the memory. # # ---------------------------------- Network ----------------------------------- # # Set the bind address to a specific IP (IPv4 or IPv6): # network.host: 127.0.0.1 # # Set a custom port for HTTP: # http.port: 9200 # # For more information, consult the network module documentation. # on the system and that the owner of the process is allowed to use this # limit. # # Elasticsearch performs poorly when the system is swapping the memory. # # ---------------------------------- Network ----------------------------------- # # Set the bind address to a specific IP (IPv4 or IPv6): # network.host: 127.0.0.1 # # Set a custom port for HTTP: # http.port: 9200 # # For more information, consult the network module documentation. # # --------------------------------- Discovery ---------------------------------- # # Pass an initial list of hosts to perform discovery when this node is started: # The default list of hosts is ["127.0.0.1", "[::1]"] # #discovery.seed_hosts: ["host1", "host2"] # # Bootstrap the cluster using an initial set of master-eligible nodes: # cluster.initial_master_nodes: ["hxx-node-1"] cluster.routing.allocation.disk.watermark.flood_stage: 99% cluster.routing.allocation.disk.threshold_enabled: false
3.安裝ik分詞庫(用於中文) 下載對應的哦 7.7.1
https://github.com/medcl/elasticsearch-analysis-ik/releases
不管你用何種方法 放到安裝路徑裡/etc/elasticsearch-7.7.1/plugins/ik
好了 切換到 elastic 然後執行elastic
su elastic ./bin/elastic -d
可進行測試
[root@iZuf64idor3ej85kby45arZ elasticsearch-7.7.1]# curl 127.0.0.1:9200 { "name" : "hxx-node-1", "cluster_name" : "hxx", "cluster_uuid" : "-43vGhX0Ru2ocVqNO7VhyA", "version" : { "number" : "7.7.1", "build_flavor" : "default", "build_type" : "tar", "build_hash" : "ad56dce891c901a492bb1ee393f12dfff473a423", "build_date" : "2020-05-28T16:30:01.040088Z", "build_snapshot" : false, "lucene_version" : "8.5.1", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search"
二、PHP部分
1.composer 引入 elastic-php(使用phpstorm更方便)
"elasticsearch/elasticsearch": "~7.0",
2.編輯elastic控制器類(包括 建立 增刪改查 批量給匯入)Ela.php
(1)執行index 後面查詢執行search
<?php // +---------------------------------------------------------------------- // | EasyAdmin // +---------------------------------------------------------------------- // | PHP交流群: 763822524 // +---------------------------------------------------------------------- // | 開源協議 https://mit-license.org // +---------------------------------------------------------------------- // | github開源專案:https://github.com/zhongshaofa/EasyAdmin // +---------------------------------------------------------------------- namespace app\index\controller; use app\admin\model\Corporation; use app\index\model\SystemUploadfile; use app\common\controller\IndexController; use app\common\service\MenuService; use EasyAdmin\upload\Uploadfile; use Elasticsearch\ClientBuilder; use Elasticsearch\Common\Exceptions\BadRequest400Exception; use Elasticsearch\Common\Exceptions\ElasticsearchException; use Elasticsearch\Common\Exceptions\Missing404Exception; use think\db\Query; use think\facade\Cache; class Ela extends IndexController { private $client; // 建構函式 public function __construct() { //$host = ['120.26.205.129:9200']; $host = ['127.0.0.1:9200']; $this->index = 'hcc_corporation'; //$this->type = 'lyric'; $this->client = ClientBuilder::create()->setHosts($host)->build(); } // 初始化 public function index() { // 只能建立一次 $this->delete_index(); $this->create_index(); //1.建立索引 $this->create_mappings(); //2.建立文件模板 /* foreach ($docs as $k => $v) { $this->add_doc($v['id'], $v); //3.新增文件 echo '<pre>'; print_r($this->get_doc($v['id'])); } exit();*/ // echo '<pre>'; // print_r($this->get_doc(512)); // exit(); // $re = $this->search_doc("我做無敵",0,2); //4.搜尋結果 // // echo '<pre>'; // print_r($re); // exit(); echo '<pre>'; print_r("INIT OK"); exit(); } public function put_settings() { $params1 = [ 'index' => $this->index, 'body' => [ 'settings' => [ 'blocks' => [ 'read_only_allow_delete' => 'false' ] ], ] ]; $this->client->indices()->putSettings($params1); echo 'SUCCESS'; } // 建立索引 public function create_index() { // 只能建立一次 $params = [ 'index' => $this->index, 'body' => [ 'settings' => [ 'number_of_shards' => 3, 'number_of_replicas' => 2, 'blocks' => [ 'read_only_allow_delete' => 'false' ], /*'transient' => [ 'cluster' => [ 'routing' => [ 'allocation' => [ 'disk' => [ 'threshold_enabled' => 'true', 'watermark' => [ 'flood_stage' => '99%' ] ] ] ] ] ]*/ ], ] ]; try { $this->client->indices()->create($params); } catch (BadRequest400Exception $e) { $msg = $e->getMessage(); $msg = json_decode($msg, true); return $msg; } } // 刪除索引 public function delete_index() { $params = ['index' => $this->index]; $index = $this->client->indices()->get($params); if ($index) { return $this->client->indices()->delete($params); } // } // 建立文件模板 public function create_mappings() { /*--------------------允許type的寫法 老版本 已去除--------------------------*/ /*--------------------不允許type的寫法--------------------------*/ // Set the index and type $params = [ 'index' => $this->index, 'body' => [ '_source' => [ 'enabled' => true ], 'properties' => [ 'id' => [ 'type' => 'integer', ], 'name' => [ 'type' => 'text', 'analyzer' => 'ik_smart' // 'analyzer' => 'keyword' ], /*-------------------------------------*/ /*'profile' => [ 'type' => 'text', 'analyzer' => 'ik_max_word' ], 'age' => [ 'type' => 'integer', ],*/ ] ] ]; $this->client->indices()->putMapping($params); /* echo '<pre>'; print_r('success'); exit();*/ } // 檢視對映 public function get_mapping() { $params = [ 'index' => $this->index, ]; $re = $this->client->indices()->getMapping($params); echo '<pre>'; print_r($re); exit(); } // 新增一個文件(記錄) public function add_doc($id, $doc) { $params = [ 'index' => $this->index, // 'type' => $this->type, 'id' => $id, 'body' => $doc ]; return $this->client->index($params); } // 判斷文件(記錄) public function exists_doc($id = 1) { $params = [ 'index' => $this->index, 'type' => $this->type, 'id' => $id ]; return $this->client->exists($params); } // 獲取一條文件(記錄) public function get_doc($id = 1) { $params = [ 'index' => $this->index, // 'type' => $this->type, 'id' => $id ]; try { $re = $this->client->get($params); } catch (Missing404Exception $e) { echo '<pre>'; print_r('未找到對應資料'); exit(); } echo '<pre>'; print_r($re); exit(); } // 更新一條文件() public function update_doc($id = 1) { // 可以靈活新增新欄位,最好不要亂新增 $params = [ 'index' => $this->index, 'id' => $id, 'body' => [ 'doc' => [ 'name' => '大王' ] ] ]; return $this->client->update($params); } // 刪除一條文件() public function delete_doc($id = 1) { $params = [ 'index' => $this->index, //'type' => $this->type, 'id' => $id ]; return $this->client->delete($params); } // 查詢文件 (分頁,排序,權重,過濾) public function search_doc($keywords = "", $from = 0, $size = 10, $order = ['id' => ['order' => 'desc']]) { /* echo '<pre>'; print_r($from); print_r($size); exit();*/ $keywords_arr = array_filter(explode(" ", $keywords)); $query = ''; $number = count($keywords_arr); if($number > 10){ return "ERROR"; } if ($number > 1) { $arr = []; foreach ($keywords_arr as $ka){ $arr[] = $ka; } $mathc_phrase = []; switch ($number){ case 2: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1] ]; break; case 3: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2] ]; break; case 4: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2], 'name'=>$arr[3], ]; break; case 5: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2], 'name'=>$arr[3], 'name'=>$arr[4], ]; break; case 6: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2], 'name'=>$arr[3], 'name'=>$arr[4], 'name'=>$arr[5], ]; break; case 7: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2], 'name'=>$arr[3], 'name'=>$arr[4], 'name'=>$arr[5], 'name'=>$arr[6], ]; break; case 8: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2], 'name'=>$arr[3], 'name'=>$arr[4], 'name'=>$arr[5], 'name'=>$arr[6], 'name'=>$arr[7], ]; break; case 9: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2], 'name'=>$arr[3], 'name'=>$arr[4], 'name'=>$arr[5], 'name'=>$arr[6], 'name'=>$arr[7], 'name'=>$arr[8], ]; break; case 10: $mathc_phrase = [ 'name'=>$arr[0], 'name'=>$arr[1], 'name'=>$arr[2], 'name'=>$arr[3], 'name'=>$arr[4], 'name'=>$arr[5], 'name'=>$arr[6], 'name'=>$arr[7], 'name'=>$arr[8], 'name'=>$arr[9], ]; break; } // $should = []; /*foreach ($keywords_arr as $k => $keyword) { // $query .= $keyword . " OR "; $mathc_phrase[] = ['name'=>$keyword]; }*/ // $query = substr($query,0,strlen($query)-3); $query_func = [ 'bool' => [ 'must' => [ //$should //$mathc_phrase /*'query_string' => [ 'default_field' => 'name', 'query' => $query ]*/ 'match_phrase'=>$mathc_phrase, /* 'match_phrase'=> [ 'name'=>'研究會', ]*/ ] ] ]; /*echo '<pre>'; print_r($query_func); exit();*/ } else { // $query = $keywords; $query_func = [ /*-----------------------------name 單欄位單匹配---------------------------*/ 'bool' => [ 'should' => [ 'match_phrase' => [ 'name' => $keywords ] ] ] ]; } if ($keywords) { $params = [ 'index' => $this->index, // 'type' => $this->type, 'body' => [ 'query' => $query_func, 'sort' => [$order], 'from' => $from, 'size' => $size ] ]; } else { $params = [ 'index' => $this->index, // 'type' => $this->type, 'body' => [ /* 'query' => [ 'match_all'=>[] ],*/ 'sort' => [$order] , 'from' => $from, 'size' => $size ] ]; } try { $re = $this->client->search($params); } catch (\Exception $e) { echo '<pre>'; print_r($e->getMessage()); exit(); } return $re; } /** * 批量插入資料到索引 */ public function insertCorporation() { $corporations = Corporation::select(); foreach ($corporations as $corporation) { $corporation = $corporation->toArray(); $this->add_doc($corporation['id'], $corporation); } echo '<pre>'; print_r('完成了'); exit(); } }