Elasticsearch是一個基於Apache Lucene(TM)的開源搜尋引擎。無論在開源還是專有領域,Lucene可以被認為是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫。
但是,Lucene只是一個庫。想要使用它,你必須使用Java來作為開發語言並將其直接整合到你的應用中,更糟糕的是,Lucene非常複雜,你需要深入瞭解檢索的相關知識來理解它是如何工作的。
Elasticsearch也使用Java開發並使用Lucene作為其核心來實現所有索引和搜尋的功能,但是它的目的是透過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜尋變得簡單。
如果沒有搜尋引擎,單單憑藉Mysql提供的簡單搜尋功能,無論在效能還是效果上都不盡如人意,繼承程式猿的折騰屬性,決定將自己的部落格插上Elasticsearch的翅膀。
安裝 Oracle JDK
sudo apt-get update
sudo apt-get install openjdk-8-jdk
安裝 Elasticsearch
-
下載
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-2.3.4.deb sudo dpkg -i elasticsearch-2.3.4.deb
目前ElasticSearch的中文分詞外掛IK最高版本為1.9.4,相容Elasticsearch的2.3.4版本。
-
安裝
sudo dpkg -i elasticsearch-2.3.4.deb
-
開機自啟動
sudo update-rc.d elasticsearch defaults 95 10 sudo service elasticsearch start
-
測試
curl http://localhost:9200
你如果你看到以下資訊,說明你的ElasticSearch已安裝成功。
{
"name" : "Peter Petruski",
"cluster_name" : "elasticsearch",
"version" : {
"number" : "2.3.4",
"build_hash" : "...(隱藏)",
"build_timestamp" : "2016-06-30T11:24:31Z",
"build_snapshot" : false,
"lucene_version" : "5.5.0"
},
"tagline" : "You Know, for Search"
}
預設情況下 Elasticsearch 的 RESTful 服務只有本機才能訪問,也就是說無法從主機訪問虛擬機器中的服務。為了方便除錯,可以修改 /etc/elasticsearch/config/elasticsearch.yml
檔案,加入以下兩行:
network.bind_host: “0.0.0.0"
network.publish_host: \_non_loopback:ipv4_
安裝中文分詞外掛 IK
Elasticsearch原裝分詞器會簡單地拆分每個漢字,沒有根據詞庫來分詞,這樣的後果就是搜尋結果很可能不是你想要的。這裡推薦使用elasticsearch-analysis-ik,支援自定義詞庫。
- 下載
wget https://github.com/medcl/elasticsearch-analysis-ik/archive/v1.9.4.tar.gz
- 解壓
tar -xvf elasticsearch-analysis-ik.tar.gz
- 使用maven打包該java專案
cd elasticsearch-analysis-ik-1.9.4 mvn package
- 在plugins目錄下建立ik目錄,並將打包好的IK外掛解壓到其中
mkdir /usr/share/elasticsearch/plugins/ik unzip target/releases/elasticsearch-analysis-ik-1.9.4.zip -d /usr/share/elasticsearch/plugins/ik/
elasticsearch-analysis-ik 的配置檔案在
~/{es_root}/plugins/ik/config/ik/
目錄,很多都是詞表,直接用文字編輯器開啟就可以修改,改完記得儲存為 utf-8 格式。
現在再啟動 Elasticsearch 服務,如果看到類似下面這樣的資訊,說明 IK Analysis 外掛已經裝好了
plugins [analysis-ik]
使用 Elasticsearch
在使用之前,先大概瞭解下ES的特點:
網上通常會將Elasticsearch和傳統關係型資料庫Mysql做一下類比:
MySQL | Elasticsearch |
---|---|
Database(資料庫) | Index (索引) |
Table(表) | Type (型別) |
Row (行) | Document (文件) |
Column (列) | Field (欄位) |
Schema (方案) | Mapping (對映) |
Index (索引) | Everything Indexed by default (所有欄位都被索引) |
SQL (結構化查詢語言) | Query DSL (查詢專用語言) |
Elasticsearch不僅僅是全文搜尋:
- 分散式的實時檔案儲存,每個欄位都被索引並可被搜尋
- 分散式的實時分析搜尋引擎
- 可以擴充套件到上百臺伺服器,處理PB級結構化或非結構化資料
分散式、實時、每個欄位、PB級,有點不明覺厲~ 不要慌,剛認識不熟悉很正常,慢慢接觸,自然就熟絡了,stop getting off track(迴歸正題),想要詳細認識ES,請移步Elasticsearch權威指南,接下來就是一步步將ES整合進專案當中:
1. 使用package
可以直接使用官方提供的package,由於不想花時間重複造輪子,我直接使用進一步封裝的第三方package。在github上有好幾個可用的,我選了Elasticquent,部分是因為名字和laravel的Eloquent比較搭(笑...)。Elasticquent提供了簡潔好用的trait,直接整合進你的Model裡,例如Article:
...
use Elasticquent\ElasticquentTrait;
class Article extends Model
{
use ElasticquentTrait;
...
}
然後就可以優雅的使用Elasticsearch了,具體如何安裝使用,請參考Elasticquent的說明文件。
2. 配置Mapping
關於Mapping(對映),我找到了一篇專門介紹它的文章(傳送們),通俗易懂。
文章中提到,mapping不僅告訴ES一個field中是什麼型別的值, 它還告訴ES如何索引資料以及資料是否能被搜尋到。
Got it! 也就是說,如果我們不配置mapping,那ES就不會知道我們是想讓它按照IK的分詞方式來進行索引咯~
到這裡,不得不說這是一個坑,目前網上的很多資料因為使用的是老版本的ES和IK,所以index和mapping的配置一般都放在es的配置檔案yml當中。但我按照那種配置方法,並沒有達到預期的分詞效果,ES還是簡單粗暴的將漢字一個個的切開,屢敗屢戰折騰兩天之後,終於想到試著使用Elasticquent說明文件裡在Model中配置mapping的方式,果然,豁然開朗:
curl -XGET 'http://localhost:9200/_analyze?analyzer=ik&pretty=true&text=%e4%bd%a0%e5%a5%bd%e9%ba%a6%e8%82%af%e5%85%88%e7%94%9f'
{
"tokens" : [ {
"token" : "你好",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "麥",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 1
}, {
"token" : "肯",
"start_offset" : 3,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
}, {
"token" : "先生",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 3
}]
}
附上我的mapping配置程式碼
protected $mappingProperties = array(
'title' => array(
'type' => 'string',
'analyzer' => 'ik_max_word'
),
'content' => array(
'type' => 'string',
'analyzer' => 'ik_max_word'
)
);
可以看出,我告訴ES,我的title和content欄位是string型別而且請按照ik的分詞方式幫我檢索。
3. 建立索引
直接使用Elasticquent提供的createIndex方法建立,如果想把現有文件全部索引,可以使用addAllToIndex方法,簡單愉快。
Article::createIndex($shards = null, $replicas = null);
Article::addAllToIndex();
4. 增刪改查
在你的控制器裡的增刪改查方法中,將Elasticquent提供的相應操作索引的方法依次加上即可,完成之後,那麼你對文件的操作就會同步ES的索引了。具體程式碼請直接移步Elasticquent開源專案中trait裡的程式碼就好,這裡不再貼出。
寫在最後
在此之前,瞭解過sphinx,使用過配置好的xunsearch,但真正自己從零開始研究全文搜尋引擎還是頭一次,中間遇到了許多坑,雖然被坑鬱悶,但也感謝這些坑,畢竟越過去就會有快感。寫這篇文章一來作為紀念和起點,二來希望能多少對別人有點幫助,因為我也是看過好多相關的文章才一點點將ES搭建完成,在這裡感謝那些樂於分享的前輩。
當然,Elasticsearch功能很強大,各種外掛各種配置,這篇文章需要完善的地方還有很多,後期會不斷更新,如果文中有錯誤或者不嚴謹的地方,歡迎留言交流。
PS. 最後貼出我專案中的Dockerfile,方便感興趣的同學使用。
原文連結:https://macken.me/article/elasticsearch-fo...
參考資料
- Elasticsearch權威指南
- 為你的站點插上ElasticSearch的翅膀
- ElasticSearch安裝中文分詞
- elasticsearch中的mapping簡介
- 使用 Elasticsearch 實現部落格站內搜尋
- elasticsearch-analysis-ik
- Elasticquent
本作品採用《CC 協議》,轉載必須註明作者和本文連結