Elasticsearch,為了搜索

Elasticsearch是一個基于Apache Lucene(TM)的開源搜索引擎。無論在開源還是專有領(lǐng)域,Lucene可以被認(rèn)為是迄今為止最先進(jìn)、性能最好的、功能最全的搜索引擎庫。

但是,Lucene只是一個庫。想要使用它,你必須使用Java來作為開發(fā)語言并將其直接集成到你的應(yīng)用中,更糟糕的是,Lucene非常復(fù)雜,你需要深入了解檢索的相關(guān)知識來理解它是如何工作的。

Elasticsearch也使用Java開發(fā)并使用Lucene作為其核心來實現(xiàn)所有索引和搜索的功能,但是它的目的是通過簡單的RESTful API來隱藏Lucene的復(fù)雜性,從而讓全文搜索變得簡單。

如果沒有搜索引擎,單單憑借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
    
  • 開機(jī)自啟動

    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"
}

默認(rèn)情況下 Elasticsearch 的 RESTful 服務(wù)只有本機(jī)才能訪問,也就是說無法從主機(jī)訪問虛擬機(jī)中的服務(wù)。為了方便調(diào)試,可以修改

/etc/elasticsearch/config/elasticsearch.yml文件,加入以下兩行:

network.bind_host: “0.0.0.0"
network.publish_host: \_non_loopback:ipv4_

安裝中文分詞插件 IK#

Elasticsearch原裝分詞器會簡單地拆分每個漢字,沒有根據(jù)詞庫來分詞,這樣的后果就是搜索結(jié)果很可能不是你想要的。這里推薦使用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目錄下創(chuàng)建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 格式。

現(xiàn)在再啟動 Elasticsearch 服務(wù),如果看到類似下面這樣的信息,說明 IK Analysis 插件已經(jīng)裝好了

plugins [analysis-ik]

使用 Elasticsearch#

在使用之前,先大概了解下ES的特點:

網(wǎng)上通常會將Elasticsearch和傳統(tǒng)關(guān)系型數(shù)據(jù)庫Mysql做一下類比:

MySQL Elasticsearch
Database(數(shù)據(jù)庫) Index (索引)
Table(表) Type (類型)
Row (行) Document (文檔)
Column (列) Field (字段)
Schema (方案) Mapping (映射)
Index (索引) Everything Indexed by default (所有字段都被索引)
SQL (結(jié)構(gòu)化查詢語言) Query DSL (查詢專用語言)

Elasticsearch不僅僅是全文搜索:

  • 分布式的實時文件存儲,每個字段都被索引并可被搜索
  • 分布式的實時分析搜索引擎
  • 可以擴(kuò)展到上百臺服務(wù)器,處理PB級結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)

分布式、實時、每個字段、PB級,有點不明覺厲~ 不要慌,剛認(rèn)識不熟悉很正常,慢慢接觸,自然就熟絡(luò)了,stop getting off track(回歸正題),想要詳細(xì)認(rèn)識ES,請移步Elasticsearch權(quán)威指南,接下來就是一步步將ES集成進(jìn)項目當(dāng)中:

1. 使用package

可以直接使用官方提供的package,由于不想花時間重復(fù)造輪子,我直接使用進(jìn)一步封裝的第三方package。在github上有好幾個可用的,我選了Elasticquent,部分是因為名字和laravel的Eloquent比較搭(笑...)。Elasticquent提供了簡潔好用的trait,直接集成進(jìn)你的Model里,例如Article:

...
use Elasticquent\ElasticquentTrait;

class Article extends Model
{
    use ElasticquentTrait;
        ...
}

然后就可以優(yōu)雅的使用Elasticsearch了,具體如何安裝使用,請參考Elasticquent的說明文檔。

2. 配置Mapping

關(guān)于Mapping(映射),我找到了一篇專門介紹它的文章(傳送們),通俗易懂。

文章中提到,mapping不僅告訴ES一個field中是什么類型的值, 它還告訴ES如何索引數(shù)據(jù)以及數(shù)據(jù)是否能被搜索到。

Got it! 也就是說,如果我們不配置mapping,那ES就不會知道我們是想讓它按照IK的分詞方式來進(jìn)行索引咯~

到這里,不得不說這是一個坑,目前網(wǎng)上的很多資料因為使用的是老版本的ES和IK,所以index和mapping的配置一般都放在es的配置文件yml當(dāng)中。但我按照那種配置方法,并沒有達(dá)到預(yù)期的分詞效果,ES還是簡單粗暴的將漢字一個個的切開,屢敗屢戰(zhàn)折騰兩天之后,終于想到試著使用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. 創(chuàng)建索引

直接使用Elasticquent提供的createIndex方法創(chuàng)建,如果想把現(xiàn)有文檔全部索引,可以使用addAllToIndex方法,簡單愉快。

Article::createIndex($shards = null, $replicas = null);
Article::addAllToIndex();

4. 增刪改查

在你的控制器里的增刪改查方法中,將Elasticquent提供的相應(yīng)操作索引的方法依次加上即可,完成之后,那么你對文檔的操作就會同步ES的索引了。具體代碼請直接移步Elasticquent開源項目中trait里的代碼就好,這里不再貼出。

寫在最后#

在此之前,了解過sphinx,使用過配置好的xunsearch,但真正自己從零開始研究全文搜索引擎還是頭一次,中間遇到了許多坑,雖然被坑郁悶,但也感謝這些坑,畢竟越過去就會有快感。寫這篇文章一來作為紀(jì)念和起點,二來希望能多少對別人有點幫助,因為我也是看過好多相關(guān)的文章才一點點將ES搭建完成,在這里感謝那些樂于分享的前輩。

當(dāng)然,Elasticsearch功能很強(qiáng)大,各種插件各種配置,這篇文章需要完善的地方還有很多,后期會不斷更新,如果文中有錯誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,歡迎留言交流。

PS. 最后貼出我項目中的Dockerfile,方便感興趣的同學(xué)使用。

原文鏈接:https://macken.me/article/elasticsearch-for-search
https://laravel-china.org/articles/2765/elasticsearch-in-order-to-search

參考資料#

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容