- Elasticsearch 是一個建置在 Apache Lucene 上的分散式搜尋和分析引擎。
- 用於日誌分析、全文搜尋、安全智慧、業務分析和營運智慧使用。
- Elasticsearch 於 PHP 上應用教學。
What is Elasticsearch?
Elasticsearch是一套基於Apache Lucene(TM)的開源搜尋引擎。無論在開源或專有禮遇,Lucene被認為至今最先進、性能最好、功能最齊全的搜尋引擎。
不過 Elasticsearch不僅僅是Lucene和全文搜尋,我們還能這樣去描述它:
- 分佈式的實時文進存儲,每個字段都被索引並可被搜尋。
- 分佈式的實時分析搜尋引擎。
- 可拓展至上百台服務器,處理PB級結構化或非結構化數據。
環境建置
第一步安裝Elasticsearch環境
安裝ES前請先確認JAVA環境已建置完成,可至CMD下指令 java -version
。
若無可至JAVA官網進行安裝及環境建置。
Elasticsearch安裝有需多不同方式(待補其他方式)。
此處筆者至Elasticsearch官網直接下載最新版並解壓縮使用。
檔案包安裝好後由CMD直接進入該專案包下指令喚醒Elasticsearch bin/elasticsearch
。
請注意喚醒ES不可使用root身份進行,並確認專案內部分檔案開放該身份存取(logs等…)
如何確認ES是否安裝成功?
可直接使用網頁連結 http://localhost:9200/
若出現畫面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "name" : "BSQmiuK", "cluster_name" : "elasticsearch", "cluster_uuid" : "d6gTLQ0-Svy1WbTWSvKmig", "version" : { "number" : "6.2.4", "build_hash" : "ccec39f", "build_date" : "2018-04-12T20:37:28.497551Z", "build_snapshot" : false, "lucene_version" : "7.2.1", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" }
|
代表大致上沒有問題。
如何在php上應用Elasticsearch?
筆者此處使用[[https://getcomposer.org/|composer]]檔案管理套件進行ES-PHP檔案安裝。
若無此套件可先進行環境建置。
PHP上使用Elasticsearch
先在專案內新增composer.json
檔並包含elasticsearch-php
(筆者編寫時最新版本需配合php7,固取得版本5.0配合PHP 5.6)。
composer.json檔內容
1 2 3 4 5
| { "require": { "elasticsearch/elasticsearch": "~5.0" } }
|
完成後cmd到專案目錄下進行 composer install
進行套件安裝。
於專案內新增index.php,使用自動加載並實例化客戶端。
1 2 3 4
| require 'vendor/autoload.php'; use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()->build();
|
建立索引資歷。將以下code添加至index.php內
1 2 3 4 5 6 7 8 9 10
| $params = [ 'index' => 'my_index', 'type' => 'my_type', 'id' => 'my_id', 'body' => ['testField' => 'abc'], ];
$response = $client->index($params); var_dump($response);
|
於網頁執行應該回得到頁面訊息
1 2 3 4 5 6 7 8 9 10 11 12 13
| array (size=8) '_index' => string 'my_index' (length=8) '_type' => string 'my_type' (length=7) '_id' => string 'my_id' (length=5) '_version' => int 6 'result' => string 'updated' (length=7) '_shards' => array (size=3) 'total' => int 2 'successful' => int 1 'failed' => int 0 '_seq_no' => int 5 '_primary_term' => int 1
|
返回response為Elasticsearch創建索引返回的JSON解碼關聯表。
依條件取得索引資料
1 2 3 4 5 6 7 8
| $params = [ 'index' => 'my_index', 'type' => 'my_type', 'id' => 'my_id', ];
$response = $client->get($params); var_dump($response);
|
我們可以依照索引設置及get取得文檔資料
1 2 3 4 5 6 7 8 9
| array (size=6) '_index' => string 'my_index' (length=8) '_type' => string 'my_type' (length=7) '_id' => string 'my_id' (length=5) '_version' => int 1 'found' => boolean true '_source' => array (size=1) 'testField' => string 'abc' (length=3)
|
依索引刪除資料
1 2 3 4 5
| $deleteParams = [ 'index' => 'my_index', ]; $response = $client->indices()->delete($deleteParams); print_r($response);
|
得到確認回應
1
| Array ( [acknowledged] => 1 )
|
關鍵字搜尋
Elasticsearch可對入稿之資料內容做比對搜尋。
關鍵字若下”後山大火雞”,那”後”、”山”、”大”、”火”、”雞”、”後山”、”火雞”(請自行依此類推)皆會成為搜尋條件並找出一定比重之資料。
讓我們來看看該怎麼做。
首先幫我入稿基本資料:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| $params = [ 'index' => 'my_index2', 'type' => 'my_type', 'body' => ['count' => '後山大火雞'], ]; $client->index($params);
$params = [ 'index' => 'my_index', 'type' => 'my_type', 'body' => ['count' => '火雞'], ]; $client->index($params);
$params = [ 'index' => 'my_index', 'type' => 'my_type', 'body' => ['count' => '後山'], ]; $client->index($params);
$params = [ 'index' => 'my_index', 'type' => 'my_type', 'body' => ['count' => '後大'], ]; $client->index($params);
|
搜尋功能應用(其中僅入稿資料”後山” 不再搜尋關鍵字 “大火雞” 拆分比對資料內因故沒被顯示出來)。
1 2 3 4 5 6 7 8 9
| $paramsSeach['body'] = array( 'query' => array( 'match' => array( 'count' => '大火雞', ), ) ); $results = $client->search($paramsSeach); var_dump($results['hits']['hits']);
|
上述指令會取得結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| array (size=3) 0 => array (size=5) '_index' => string 'my_index' (length=8) '_type' => string 'my_type' (length=7) '_id' => string 'S2fIPmMBYbAZcmkxgr3x' (length=20) '_score' => float 1.3862944 '_source' => array (size=1) 'count' => string '火雞' (length=6) 1 => array (size=5) '_index' => string 'my_index2' (length=9) '_type' => string 'my_type' (length=7) '_id' => string 'SmfIPmMBYbAZcmkxgr2d' (length=20) '_score' => float 0.8630463 '_source' => array (size=1) 'count' => string '後山大火雞' (length=15) 2 => array (size=5) '_index' => string 'my_index' (length=8) '_type' => string 'my_type' (length=7) '_id' => string 'TWfIPmMBYbAZcmkxg70I' (length=20) '_score' => float 0.2876821 '_source' => array (size=1) 'count' => string '後大' (length=6)
|
搜尋應用還可對指定索引進行搜尋,於上方資料後山大火雞
可發現其陣列內index
欄位與其他幾項不同。
此時只要添加索引條件:
1
| $paramsSeach['index'] = 'my_index';
|
由於此處指定搜尋index
,故會發現搜尋搜尋結果以濾掉 ['index' => 'my_index2']
的 後山大火雞
。
以上為Elasticsearch-php基本應用。
其實有許多功能筆者皆未提到。
例: Elasticsearch監聽程式(Elasticsearch-head)、或全域搜尋功能。還有許多分析功能。
待筆者日後對Elasticsearch掌握度更加精進後,在進行文件補充動作
以下附上DB相關進階應用:
DB與ES數據庫連結(conn.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <?php require_once 'vendor/autoload.php';
//連結MySql資料庫 function get_conn() { @$conn = mysql_connect("localhost", "root", "root") or die("error connecting"); mysql_select_db("DBName", $conn); # *DB請自行填入 mysql_query("SET NAMES 'UTF8'"); return $conn; }
//由DB取得資料並回存ES中 function create_index($maxId, $client) { //取捯DB資料 $sql = "SELECT * FROM tableName where id > $maxId limit 0,300"; # *資料表名稱請自行填入 get_conn(); @$result_bugs = mysql_query($sql); while (@$row = mysql_fetch_assoc(@$result_bugs)) { $rtn[] = $row; }
foreach ($rtn as $val) { $params = array(); $params['body'] = array( 'id' => $val['id'], 'count' => $val['count'], # *請自行修改比對欄位及名稱 ); $params['index'] = 'index'; $params['type'] = 'title';
$client->index($params); }
return (count($rtn) == 300) ? $val['id'] : false; }
// set_time_limit(0); $client = Elasticsearch\ClientBuilder::create()->setHosts(['localhost'])->build(); //刪除所有數據 // $client->indices()->delete(['index' => 'index']);
$a = true; $maxId = 0; while ($a) { $maxId = create_index($maxId, $client); if (empty($maxId)) { $a = false; } }
|
執行php(testConn.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <?php //引入DB連結 require 'conn.php'; require_once 'vendor/autoload.php'; function search($keyword, $page = 0, $size = 20) { //實體化對象 $client = Elasticsearch\ClientBuilder::create()->setHosts(['localhost'])->build(); //查詢數據庫拼裝 $params = array(); $params['index'] = 'index'; $params['type'] = 'title'; $params['body']['query']['match']['count'] = $keyword; $params['from'] = $page; $params['size'] = $size;
//查詢 $rtn = $client->search($params)['hits'];
//結果組裝 $data['total'] = $rtn['total']; $data['lists'] = array_column($rtn['hits'], '_source'); $data['lists'] = formartData(array_column($data['lists'], 'id'));
return $data; }
function formartData($ids) { $ids = implode($ids, ','); $sql = "select * from articles where id in($ids)"; $data = mysql_query($sql);
$rtn = []; while (@$row = mysql_fetch_assoc(@$data)) { $rtn[] = $row; }
return $rtn; }
$q0 = isset($_GET['q']) ? $_GET['q'] : 'SQL注入'; $num = "15"; //每頁顯示比數 $page = isset($_GET['page']) ? intval($_GET['page']) : 1; $offset = ($page - 1) * $num; $esData = search($q0, $offset, $num);
var_dump($esData);
|
使用方式:呼叫程式並賦予搜尋值。
1 2
| http://localhost/testConn.php?q=
|
- 注意1:
索引(index)
與 型態(type)
設定時必須小寫。
聲明:此篇教學僅提供學習與交流使用,請勿用於商業用途。
參考資料